01 贪食蛇玩法介绍以及编码分析
02贪食蛇墙模块实现
代码结构:
wall.h:
#ifndef _WALL_HEAD
#define _WALL_HEAD
#include<iostream>
using namespace std;
class Wall
{
public:
enum {
ROW = 20,
COL = 20
};
//初始化墙壁
void initWall();
//画出墙壁
void drawWall();
//根据索引设置,二维数组里的内容
void setWall(int x, int y, char c);
//根据索引获取当前位置的符号
char getWall(int x, int y);
private:
char gameArray[ROW][COL];
};
#endif // !_WALL_HEAD
wall.cpp:
#include"wall.h"
void Wall::initWall()
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
//放墙壁
if (i == 0 || j == 0 || i == ROW - 1 || j == COL - 1)
{
gameArray[i][j] = '*';
}
else
{
gameArray[i][j] = ' ';
}
}
}
}
void Wall::drawWall()
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
cout << gameArray[i][j] << " ";
}
if (i == 5)
{
cout << "create by zt";
}
if (i == 6)
{
cout << "a:left";
}
if (i == 7)
{
cout << "b:right";
}
if (i == 8)
{
cout << "w:up";
}
if (i == 9)
{
cout << "s:down";
}
cout << endl;
}
}
void Wall::setWall(int x, int y, char c)
{
gameArray[x][y] = c;
}
char Wall::getWall(int x, int y)
{
return gameArray[x][y];
}
game.cpp:
#include<iostream>
using namespace std;
#include"wall.h"
int main()
{
Wall wall;
wall.initWall();
//测试
wall.setWall(5, 4, '=');
wall.setWall(5, 5, '=');
wall.setWall(5, 6, '@');
wall.drawWall();
cout << wall.getWall(0, 0) << endl;
cout << wall.getWall(5, 4) << endl;
cout << wall.getWall(5, 6) << endl;
cout << wall.getWall(1, 1) << endl;
system("pause");
return EXIT_SUCCESS;
}
03 贪食蛇案例-蛇模块
代码结构:
snake.h:
#pragma once
#include<iostream>
#include"wall.h"
using namespace std;
class Snake
{
public:
Snake(Wall & tempWall);
//节点
struct Point
{
//数据域
int x;
int y;
//指针域
Point* next;
};
void initSnake();
//销毁节点
void destroyPoint();
//添加节点
void addPoint(int x, int y);
Point* pHead;
Wall& wall;
};
snake.cpp:
#include "snake.h"
Snake::Snake(Wall& tempWall):wall(tempWall)
{
pHead = NULL;
}
void Snake::initSnake()
{
destroyPoint();
addPoint(5, 3);
addPoint(5, 4);
addPoint(5, 5);
}
void Snake::destroyPoint()
{
Point* pCur = pHead;
while (pHead != NULL)
{
pCur = pHead->next;
delete pHead;
pHead = pCur;
}
}
void Snake::addPoint(int x, int y)
{
//创建新节点
Point* newPoint = new Point;
newPoint->x = x;
newPoint->y = y;
newPoint->next = NULL;
//如果原来头不为空,改为 身子
if (pHead != NULL)
{
wall.setWall(pHead->x, pHead->y, '=');
}
newPoint->next = pHead;
pHead = newPoint;//更新头部
wall.setWall(pHead->x, pHead -> y, '@');
}
game.cpp:
#include<iostream>
using namespace std;
#include"wall.h"
#include"snake.h"
int main()
{
Wall wall;
wall.initWall();
Snake snake(wall);
snake.initSnake();
wall.drawWall();
system("pause");
return EXIT_SUCCESS;
}
04 贪食蛇-食物模块
代码结构:
food.h:
#pragma once
#include<iostream>
using namespace std;
#include"wall.h"
class Food
{
public:
Food(Wall& tempWall);
//设置食物
void setFood();
int foodX;
int foodY;
Wall& wall;
};
food.cpp:
#include "food.h"
Food::Food(Wall& tempWall):wall(tempWall)
{
}
void Food::setFood()
{
while (true)
{
foodX = rand() % (Wall::ROW - 2) + 1;
foodY = rand() % (Wall::COL - 2) + 1;
//如果随机的位置是蛇头或蛇身,就重新生成随机数
if (wall.getWall(foodX, foodY) == ' ')
{
wall.setWall(foodX, foodY, '#');
break;
}
}
}
game.cpp:
#include<iostream>
using namespace std;
#include"wall.h"
#include"snake.h"
#include"food.h"
#include<ctime>
int main()
{
//添加随机种子
srand((unsigned int)time(NULL));
Wall wall;
wall.initWall();
Snake snake(wall);
snake.initSnake();
Food food(wall);
food.setFood();
wall.drawWall();
system("pause");
return EXIT_SUCCESS;
}
05 删除尾节点和移动封装
snake.h:
#pragma once
#include<iostream>
#include"wall.h"
#include"food.h"
using namespace std;
class Snake
{
public:
Snake(Wall & tempWall,Food & ftmpFood);
enum{ UP = 'w',DOWN ='s',LEFT='a',RIGHT='d' };
//节点
struct Point
{
//数据域
int x;
int y;
//指针域
Point* next;
};
void initSnake();
//销毁节点
void destroyPoint();
//添加节点
void addPoint(int x, int y);
//删除节点
void delPoint();
//移动蛇操作
//返回值代表移动施法成功
bool move(char key);
Point* pHead;
Wall& wall;
Food& food;
};
snake.cpp:
#include "snake.h"
Snake::Snake(Wall& tempWall, Food& tmpFood) :wall(tempWall), food(tmpFood)
{
pHead = NULL;
}
void Snake::initSnake()
{
destroyPoint();
addPoint(5, 3);
addPoint(5, 4);
addPoint(5, 5);
}
void Snake::destroyPoint()
{
Point* pCur = pHead;
while (pHead != NULL)
{
pCur = pHead->next;
delete pHead;
pHead = pCur;
}
}
void Snake::addPoint(int x, int y)
{
//创建新节点
Point* newPoint = new Point;
newPoint->x = x;
newPoint->y = y;
newPoint->next = NULL;
//如果原来头不为空,改为 身子
if (pHead != NULL)
{
wall.setWall(pHead->x, pHead->y, '=');
}
newPoint->next = pHead;
pHead = newPoint;//更新头部
wall.setWall(pHead->x, pHead -> y, '@');
}
//删除节点
void Snake::delPoint()
{
//两个节点以上,才去做删除操作
if (pHead == NULL || pHead->next == NULL)
{
return;
}
Point* pCur = pHead->next;
Point* pPre = pHead;
while (pCur->next != NULL)
{
pPre = pPre->next;
pCur = pCur->next;
}
//删除尾节点
wall.setWall(pCur->x, pCur->y, ' ');
delete pCur;
pCur = NULL;
pPre->next = NULL;
}
bool Snake::move(char key)
{
int x = pHead->x;
int y = pHead->y;
switch (key)
{
case UP:
x--;
break;
case DOWN :
x++;
break;
case LEFT:
y--;
break;
case RIGHT:
y++;
break;
default:
break;
}
//判断用户到达位置是否成功
if (wall.getWall(x, y) == '*' || wall.getWall(x, y) == '=')
{
cout << "GAME OVER!!!" << endl;
return false;
}
//移动成功,分两种
//吃到食物,未吃到食物
if (wall.getWall(x, y) == '#')
{
addPoint(x, y);
//重新设置食物
food.setFood();
}
else
{
addPoint(x, y);
delPoint();
}
return true;
}
game.cpp:
#include<iostream>
using namespace std;
#include"wall.h"
#include"snake.h"
#include"food.h"
#include<ctime>
int main()
{
//添加随机种子
srand((unsigned int)time(NULL));
Wall wall;
wall.initWall();
Food food(wall);
food.setFood();
Snake snake(wall,food);
snake.initSnake();
wall.drawWall();
system("pause");
return EXIT_SUCCESS;
}
06 蛇移动以及bug的解决
snake.h:
#pragma once
#include<iostream>
#include"wall.h"
#include"food.h"
using namespace std;
class Snake
{
public:
Snake(Wall & tempWall,Food & ftmpFood);
enum{ UP = 'w',DOWN ='s',LEFT='a',RIGHT='d' };
//节点
struct Point
{
//数据域
int x;
int y;
//指针域
Point* next;
};
void initSnake();
//销毁节点
void destroyPoint();
//添加节点
void addPoint(int x, int y);
//删除节点
void delPoint();
//移动蛇操作
//返回值代表移动施法成功
bool move(char key);
Point* pHead;
Wall& wall;
Food& food;
bool isRool;//判断循环标示
};
snake.cpp:
#include "snake.h"
Snake::Snake(Wall& tempWall, Food& tmpFood) :wall(tempWall), food(tmpFood)
{
pHead = NULL;
isRool = false;
}
void Snake::initSnake()
{
destroyPoint();
addPoint(5, 3);
addPoint(5, 4);
addPoint(5, 5);
}
void Snake::destroyPoint()
{
Point* pCur = pHead;
while (pHead != NULL)
{
pCur = pHead->next;
delete pHead;
pHead = pCur;
}
}
void Snake::addPoint(int x, int y)
{
//创建新节点
Point* newPoint = new Point;
newPoint->x = x;
newPoint->y = y;
newPoint->next = NULL;
//如果原来头不为空,改为 身子
if (pHead != NULL)
{
wall.setWall(pHead->x, pHead->y, '=');
}
newPoint->next = pHead;
pHead = newPoint;//更新头部
wall.setWall(pHead->x, pHead -> y, '@');
}
//删除节点
void Snake::delPoint()
{
//两个节点以上,才去做删除操作
if (pHead == NULL || pHead->next == NULL)
{
return;
}
Point* pCur = pHead->next;
Point* pPre = pHead;
while (pCur->next != NULL)
{
pPre = pPre->next;
pCur = pCur->next;
}
//删除尾节点
wall.setWall(pCur->x, pCur->y, ' ');
delete pCur;
pCur = NULL;
pPre->next = NULL;
}
bool Snake::move(char key)
{
int x = pHead->x;
int y = pHead->y;
switch (key)
{
case UP:
x--;
break;
case DOWN :
x++;
break;
case LEFT:
y--;
break;
case RIGHT:
y++;
break;
default:
break;
}
//判断,如果是下一步碰到的是尾巴,不应该死亡
Point* pCur = pHead->next;
Point* pPre = pHead;
while (pCur->next != NULL)
{
pPre = pPre->next;
pCur = pCur->next;
}
if (pCur->x == x && pCur->y == y)
{
//碰到尾巴 循环
isRool = true;
}
else
{
//判断用户到达位置是否成功
if (wall.getWall(x, y) == '*' || wall.getWall(x, y) == '=')
{
addPoint(x, y);
destroyPoint();
system("cls");
cout << "GAME OVER!!!" << endl;
return false;
}
}
//移动成功,分两种
//吃到食物,未吃到食物
if (wall.getWall(x, y) == '#')
{
addPoint(x, y);
//重新设置食物
food.setFood();
}
else
{
addPoint(x, y);
delPoint();
if (isRool == true)
{
wall.setWall(x, y, '@');
}
}
return true;
}
game.cpp:
#include<iostream>
using namespace std;
#include"wall.h"
#include"snake.h"
#include"food.h"
#include<ctime>
#include<conio.h>
#include<windows.h>
int main()
{
//添加随机种子
srand((unsigned int)time(NULL));
//是否死亡标示
bool isDead = false;
char preKey = NULL;
Wall wall;
wall.initWall();
Food food(wall);
food.setFood();
Snake snake(wall,food);
snake.initSnake();
wall.drawWall();
while (!isDead)
{
char key = _getch();
//判断 如果是第一次按了,左键,才不能激活游戏
//判断上一次 移动方向
if (preKey == NULL && key == snake.LEFT)
{
continue;
}
do {
if (key == snake.UP || key == snake.DOWN || key == snake.LEFT || key == snake.RIGHT)
{
//判断本次按键是否与上次冲突
if ((key==snake.LEFT && preKey==snake.RIGHT)||
(key == snake.RIGHT && preKey == snake.LEFT) ||
(key == snake.UP && preKey == snake.DOWN) ||
(key == snake.DOWN && preKey == snake.UP) )
{
key = preKey;
}
else
{
preKey = key;//不是冲突按键,可以更新按键
}
if (snake.move(key) == true)
{
//移动成功 代码
system("cls");
wall.drawWall();
Sleep(300);
}
else
{
isDead = true;
break;
}
}
else
{
key = preKey;//强制将错误按键变为 上一次移动的方向
}
} while (!_kbhit());//当没有键盘输入的时候,返回0
}
system("pause");
return EXIT_SUCCESS;
}
07 辅助玩法、难度和分数
snake.h:
#pragma once
#include<iostream>
#include"wall.h"
#include"food.h"
using namespace std;
class Snake
{
public:
Snake(Wall & tempWall,Food & ftmpFood);
enum{ UP = 'w',DOWN ='s',LEFT='a',RIGHT='d' };
//节点
struct Point
{
//数据域
int x;
int y;
//指针域
Point* next;
};
void initSnake();
//销毁节点
void destroyPoint();
//添加节点
void addPoint(int x, int y);
//删除节点
void delPoint();
//移动蛇操作
//返回值代表移动施法成功
bool move(char key);
//设置难度
//获取刷屏时间
int getSleepTime();
//获取蛇身段
int countList();
//获取分数
int getScore();
Point* pHead;
Wall& wall;
Food& food;
bool isRool;//判断循环标示
};
snake.cpp:
#include "snake.h"
Snake::Snake(Wall& tempWall, Food& tmpFood) :wall(tempWall), food(tmpFood)
{
pHead = NULL;
isRool = false;
}
void Snake::initSnake()
{
destroyPoint();
addPoint(5, 3);
addPoint(5, 4);
addPoint(5, 5);
}
void Snake::destroyPoint()
{
Point* pCur = pHead;
while (pHead != NULL)
{
pCur = pHead->next;
delete pHead;
pHead = pCur;
}
}
void Snake::addPoint(int x, int y)
{
//创建新节点
Point* newPoint = new Point;
newPoint->x = x;
newPoint->y = y;
newPoint->next = NULL;
//如果原来头不为空,改为 身子
if (pHead != NULL)
{
wall.setWall(pHead->x, pHead->y, '=');
}
newPoint->next = pHead;
pHead = newPoint;//更新头部
wall.setWall(pHead->x, pHead -> y, '@');
}
//删除节点
void Snake::delPoint()
{
//两个节点以上,才去做删除操作
if (pHead == NULL || pHead->next == NULL)
{
return;
}
Point* pCur = pHead->next;
Point* pPre = pHead;
while (pCur->next != NULL)
{
pPre = pPre->next;
pCur = pCur->next;
}
//删除尾节点
wall.setWall(pCur->x, pCur->y, ' ');
delete pCur;
pCur = NULL;
pPre->next = NULL;
}
bool Snake::move(char key)
{
int x = pHead->x;
int y = pHead->y;
switch (key)
{
case UP:
x--;
break;
case DOWN :
x++;
break;
case LEFT:
y--;
break;
case RIGHT:
y++;
break;
default:
break;
}
//判断,如果是下一步碰到的是尾巴,不应该死亡
Point* pCur = pHead->next;
Point* pPre = pHead;
while (pCur->next != NULL)
{
pPre = pPre->next;
pCur = pCur->next;
}
if (pCur->x == x && pCur->y == y)
{
//碰到尾巴 循环
isRool = true;
}
else
{
//判断用户到达位置是否成功
if (wall.getWall(x, y) == '*' || wall.getWall(x, y) == '=')
{
addPoint(x, y);
destroyPoint();
system("cls");
cout << "得分:" << getScore() << "分" << endl;
cout << "GAME OVER!!!" << endl;
return false;
}
}
//移动成功,分两种
//吃到食物,未吃到食物
if (wall.getWall(x, y) == '#')
{
addPoint(x, y);
//重新设置食物
food.setFood();
}
else
{
addPoint(x, y);
delPoint();
if (isRool == true)
{
wall.setWall(x, y, '@');
}
}
return true;
}
int Snake::getSleepTime()
{
int sleepTime = 0;
int size = countList();
if (size < 5)
{
sleepTime = 300;
}
else if (size >= 5 && size <= 8)
{
sleepTime = 200;
}
else
{
sleepTime = 100;
}
return sleepTime;
}
int Snake::countList()
{
int size = 0;
Point* curPoint = pHead;
while (curPoint != NULL)
{
size++;
curPoint = curPoint->next;
}
return size;
}
int Snake::getScore()
{
int size = countList();
int score = (size - 3) * 100;
return score;
}
game.cpp:
#include<iostream>
using namespace std;
#include"wall.h"
#include"snake.h"
#include"food.h"
#include<ctime>
#include<conio.h>
#include<windows.h>
int main()
{
//添加随机种子
srand((unsigned int)time(NULL));
//是否死亡标示
bool isDead = false;
char preKey = NULL;
Wall wall;
wall.initWall();
Food food(wall);
food.setFood();
Snake snake(wall,food);
snake.initSnake();
wall.drawWall();
cout << "得分:" << snake.getScore() << "分" << endl;
while (!isDead)
{
char key = _getch();
//判断 如果是第一次按了,左键,才不能激活游戏
//判断上一次 移动方向
if (preKey == NULL && key == snake.LEFT)
{
continue;
}
do {
if (key == snake.UP || key == snake.DOWN || key == snake.LEFT || key == snake.RIGHT)
{
//判断本次按键是否与上次冲突
if ((key==snake.LEFT && preKey==snake.RIGHT)||
(key == snake.RIGHT && preKey == snake.LEFT) ||
(key == snake.UP && preKey == snake.DOWN) ||
(key == snake.DOWN && preKey == snake.UP) )
{
key = preKey;
}
else
{
preKey = key;//不是冲突按键,可以更新按键
}
if (snake.move(key) == true)
{
//移动成功 代码
system("cls");
wall.drawWall();
cout << "得分:" << snake.getScore() << "分" << endl;
Sleep(snake.getSleepTime());
}
else
{
isDead = true;
break;
}
}
else
{
key = preKey;//强制将错误按键变为 上一次移动的方向
}
} while (!_kbhit());//当没有键盘输入的时候,返回0
}
system("pause");
return EXIT_SUCCESS;
}
08 优化游戏
gotoxy函数可以任意移动位置,进行输出输入。
gotoxy有一个特别有用的作用,比如,你移到第3行第2格,输出"123",但是你还想移到第1行第1格输出"123",如果不用gotoxy函数,是做不到的,但是gotoxy可以做到
void gotoxy(int x, int y) {
COORD pos = {x,y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, pos);
}
wall.h:
#ifndef _WALL_HEAD
#define _WALL_HEAD
#include<iostream>
using namespace std;
class Wall
{
public:
enum {
ROW = 26,
COL = 26
};
//初始化墙壁
void initWall();
//画出墙壁
void drawWall();
//根据索引设置,二维数组里的内容
void setWall(int x, int y, char c);
//根据索引获取当前位置的符号
char getWall(int x, int y);
private:
char gameArray[ROW][COL];
};
#endif // !_WALL_HEAD
wall.cpp:
#include"wall.h"
void Wall::initWall()
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
//放墙壁
if (i == 0 || j == 0 || i == ROW - 1 || j == COL - 1)
{
gameArray[i][j] = '*';
}
else
{
gameArray[i][j] = ' ';
}
}
}
}
void Wall::drawWall()
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
cout << gameArray[i][j] << " ";
}
if (i == 5)
{
cout << "create by zt";
}
if (i == 6)
{
cout << "a:left";
}
if (i == 7)
{
cout << "b:right";
}
if (i == 8)
{
cout << "w:up";
}
if (i == 9)
{
cout << "s:down";
}
cout << endl;
}
}
void Wall::setWall(int x, int y, char c)
{
gameArray[x][y] = c;
}
char Wall::getWall(int x, int y)
{
return gameArray[x][y];
}
food.h:
#pragma once
#include<iostream>
using namespace std;
#include"wall.h"
class Food
{
public:
Food(Wall& tempWall);
//设置食物
void setFood();
int foodX;
int foodY;
Wall& wall;
};
food.cpp:
#include "food.h"
#include<Windows.h>
void gotoxy2(HANDLE hOut2, int x, int y) {
COORD pos = { x,y };
SetConsoleCursorPosition(hOut2, pos);
}
HANDLE hOut2 = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
Food::Food(Wall& tempWall):wall(tempWall)
{
}
void Food::setFood()
{
while (true)
{
foodX = rand() % (Wall::ROW - 1) + 1;
foodY = rand() % (Wall::COL - 1) + 1;
//如果随机的位置是蛇头或蛇身,就重新生成随机数
if (wall.getWall(foodX, foodY) == ' ')
{
wall.setWall(foodX, foodY, '#');
gotoxy2(hOut2, foodY * 2, foodX);
cout << "#";
break;
}
}
}
snake.h:
#pragma once
#include<iostream>
#include"wall.h"
#include"food.h"
using namespace std;
class Snake
{
public:
Snake(Wall & tempWall,Food & ftmpFood);
enum{ UP = 'w',DOWN ='s',LEFT='a',RIGHT='d' };
//节点
struct Point
{
//数据域
int x;
int y;
//指针域
Point* next;
};
void initSnake();
//销毁节点
void destroyPoint();
//添加节点
void addPoint(int x, int y);
//删除节点
void delPoint();
//移动蛇操作
//返回值代表移动施法成功
bool move(char key);
//设置难度
//获取刷屏时间
int getSleepTime();
//获取蛇身段
int countList();
//获取分数
int getScore();
Point* pHead;
Wall& wall;
Food& food;
bool isRool;//判断循环标示
};
snake.cpp:
#include "snake.h"
#include<Windows.h>
void gotoxy1(HANDLE hOut1, int x, int y) {
COORD pos = { x,y };
SetConsoleCursorPosition(hOut1, pos);
}
HANDLE hOut1 = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
Snake::Snake(Wall& tempWall, Food& tmpFood) :wall(tempWall), food(tmpFood)
{
pHead = NULL;
isRool = false;
}
void Snake::initSnake()
{
destroyPoint();
addPoint(5, 3);
addPoint(5, 4);
addPoint(5, 5);
}
void Snake::destroyPoint()
{
Point* pCur = pHead;
while (pHead != NULL)
{
pCur = pHead->next;
delete pHead;
pHead = pCur;
}
}
void Snake::addPoint(int x, int y)
{
//创建新节点
Point* newPoint = new Point;
newPoint->x = x;
newPoint->y = y;
newPoint->next = NULL;
//如果原来头不为空,改为 身子
if (pHead != NULL)
{
wall.setWall(pHead->x, pHead->y, '=');
gotoxy1(hOut1, pHead->y * 2, pHead->x);
cout << "=";
}
newPoint->next = pHead;
pHead = newPoint;//更新头部
wall.setWall(pHead->x, pHead -> y, '@');
gotoxy1(hOut1, pHead->y * 2, pHead->x);
cout << "@";
}
//删除节点
void Snake::delPoint()
{
//两个节点以上,才去做删除操作
if (pHead == NULL || pHead->next == NULL)
{
return;
}
Point* pCur = pHead->next;
Point* pPre = pHead;
while (pCur->next != NULL)
{
pPre = pPre->next;
pCur = pCur->next;
}
//删除尾节点
wall.setWall(pCur->x, pCur->y, ' ');
gotoxy1(hOut1, pCur->y * 2, pCur->x);
cout << " ";
delete pCur;
pCur = NULL;
pPre->next = NULL;
}
bool Snake::move(char key)
{
int x = pHead->x;
int y = pHead->y;
switch (key)
{
case UP:
x--;
break;
case DOWN :
x++;
break;
case LEFT:
y--;
break;
case RIGHT:
y++;
break;
default:
break;
}
//判断,如果是下一步碰到的是尾巴,不应该死亡
Point* pCur = pHead->next;
Point* pPre = pHead;
while (pCur->next != NULL)
{
pPre = pPre->next;
pCur = pCur->next;
}
if (pCur->x == x && pCur->y == y)
{
//碰到尾巴 循环
isRool = true;
}
else
{
//判断用户到达位置是否成功
if (wall.getWall(x, y) == '*' || wall.getWall(x, y) == '=')
{
//addPoint(x, y);
//destroyPoint();
system("cls");
cout << "得分:" << getScore() << "分" << endl;
cout << "GAME OVER!!!" << endl;
return false;
}
}
//移动成功,分两种
//吃到食物,未吃到食物
if (wall.getWall(x, y) == '#')
{
addPoint(x, y);
//重新设置食物
food.setFood();
}
else
{
addPoint(x, y);
delPoint();
if (isRool == true)
{
wall.setWall(x, y, '@');
gotoxy1(hOut1, pHead->y * 2, pHead->x);
cout << "@";
}
}
return true;
}
int Snake::getSleepTime()
{
int sleepTime = 0;
int size = countList();
if (size < 5)
{
sleepTime = 300;
}
else if (size >= 5 && size <= 8)
{
sleepTime = 200;
}
else
{
sleepTime = 100;
}
return sleepTime;
}
int Snake::countList()
{
int size = 0;
Point* curPoint = pHead;
while (curPoint != NULL)
{
size++;
curPoint = curPoint->next;
}
return size;
}
int Snake::getScore()
{
int size = countList();
int score = (size - 3) * 100;
return score;
}
game.cpp:
#include<iostream>
using namespace std;
#include"wall.h"
#include"snake.h"
#include"food.h"
#include<ctime>
#include<conio.h>
#include<windows.h>
void gotoxy(HANDLE hOut,int x, int y) {
COORD pos = { x,y };
SetConsoleCursorPosition(hOut, pos);
}
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
int main()
{
//添加随机种子
srand((unsigned int)time(NULL));
//是否死亡标示
bool isDead = false;
char preKey = NULL;
Wall wall;
wall.initWall();
wall.drawWall();
Food food(wall);
food.setFood();
Snake snake(wall,food);
snake.initSnake();
gotoxy(hOut, Wall::COL * 2, Wall::ROW);//y*2 y
cout << "得分:" << snake.getScore() << "分" << endl;
while (!isDead)
{
char key = _getch();
//判断 如果是第一次按了,左键,才不能激活游戏
//判断上一次 移动方向
if (preKey == NULL && key == snake.LEFT)
{
continue;
}
do {
if (key == snake.UP || key == snake.DOWN || key == snake.LEFT || key == snake.RIGHT)
{
//判断本次按键是否与上次冲突
if ((key==snake.LEFT && preKey==snake.RIGHT)||
(key == snake.RIGHT && preKey == snake.LEFT) ||
(key == snake.UP && preKey == snake.DOWN) ||
(key == snake.DOWN && preKey == snake.UP) )
{
key = preKey;
}
else
{
preKey = key;//不是冲突按键,可以更新按键
}
if (snake.move(key) == true)
{
//移动成功 代码
//system("cls");
//wall.drawWall();
gotoxy(hOut, Wall::COL * 2, Wall::ROW );
cout << "得分:" << snake.getScore() << "分" << endl;
Sleep(snake.getSleepTime());
}
else
{
isDead = true;
break;
}
}
else
{
key = preKey;//强制将错误按键变为 上一次移动的方向
}
} while (!_kbhit());//当没有键盘输入的时候,返回0
}
system("pause");
return EXIT_SUCCESS;
}