一,项目简介
距上个项目(C++实现推箱子游戏)一周时间,再次回顾儿时经典游戏--贪吃蛇。
实现了按键控制蛇头移动,按下空格键暂停,采用链表结构实现吃到食物蛇身增长,到达一定限度,蛇头前进速率加快;撞到墙壁或蛇身,游戏结束。
----如有问题,希望大佬指导纠错。
二,代码区
Game.h :
#define _SNAKE_H__
#ifdef _SNAKE_H__
#include<iostream>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<list>
#include<string>
using namespace std;
#define M 20
#define N 20
//游戏类
class Game
{
public:
Game();
~Game();
void Start(void);
void Draw(void) const;
void CreatFood();
void ClockSystem(void);
private:
COORD zz; //缓存前进的点
list<COORD> snake; //链表保存蛇节点
int map[M][N]; //地图
int direction; //蛇头前进的方向
int score; //分数
int level; //游戏等级
int rate; //蛇前进速率
};
#endif /*_SNAKE_H__*/
Game.cpp :
#include"Game.h"
//构造函数,初始化游戏
Game::Game()
{
level = 0;
rate = 800;
score = 0;
direction = 1;
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
if (0 == i || M - 1 == i
|| 0 == j || N - 1 == j)
map[i][j] = 1;
else
map[i][j] = 0;
}
}
//设置初始蛇头节点
zz.X = 10, zz.Y = 7;
snake.push_front(zz);
}
//析构函数
Game::~Game()
{
}
//开始游戏
void Game::Start(void)
{
Draw();
cout << "按任意键开始";
while (!_kbhit());
char ch = _getch();
system("cls");
Draw();
ClockSystem();
}
//绘制打印地图界面
void Game::Draw(void) const
{
//system("cls");
cout <<"\t\t"<<"****************贪吃蛇小游戏****************" <<endl;
cout << "\t\t" << "* 得分:" << score << "\t\t\t " << " 等级:" << level << " *" << endl;
cout <<"\t\t"<<"* w-W:上 s-S:下 a-A:左 d-D:右 空格:暂停 *"<< endl;
for (int i = 0; i < M ; i++)
{
cout << " ";
for (int j = 0; j < N; j++)
{
switch (map[i][j])
{
//打印空地
case 0:
cout << " ";
break;
//打印墙壁
case 1:
cout << "■";
break;
//打印蛇头
case 2:
cout << "●";
break;
//打印蛇身
case 3:
cout << "◆";
break;
//打印食物
case 4:
cout << "◎";
break;
default:
break;
}
}
cout << endl; //换行
}
}
//随机生成食物
void Game::CreatFood()
{
int x, y;
do
{
x = rand() % 18 + 1;
y = rand() % 18 + 1;
} while (map[x][y] != 0);
map[x][y] = 4;
}
//时钟系统,控制游戏进行
void Game::ClockSystem(void)
{
double Start = clock();
char ch = 'w'; //初始化前进方向
bool flag; //判断当前地图中是否有食物
CreatFood();
while (1)
{
while ((clock() - Start) < rate && !(flag = (bool)_kbhit()));
Start = clock();
if (flag)
{
ch = _getch();
int _direction;
if (ch == ' ') //空格暂停
{
while (!_kbhit());
ch = _getch();
Start = clock();
}
switch (ch) //按键判断移动方向
{
case 'w':case 'W':_direction = 1; break;
case 'a':case 'A':_direction = 3; break;
case 's':case 'S':_direction = 4; break;
case 'd':case 'D':_direction = 2; break;
default:
_direction = 0;
break;
}
if (_direction + direction != 5 && _direction != 0) //如果输入的方向不和现在前进的方向冲突 就改变
direction = _direction;
}
switch (direction)
{
case 1:zz.X = snake.front().X; zz.Y = snake.front().Y - 1; break;
case 2:zz.X = snake.front().X + 1; zz.Y = snake.front().Y; break;
case 3:zz.X = snake.front().X - 1; zz.Y = snake.front().Y; break;
case 4:zz.X = snake.front().X; zz.Y = snake.front().Y + 1; break;
}
if (map[zz.Y][zz.X] == 1 || map[zz.Y][zz.X] == 3) //下一步是墙壁/蛇身
{
COORD coord;
coord.X = 3;
coord.Y = 8;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
cout << "游戏结束" << endl;
Sleep(300);
break;
}
else if (map[zz.Y][zz.X] == 4) //下一步是食物
{
score++; level = score / 10; //分数累加
level = min(5, level);
rate = 800 - level * 100;
map[snake.front().Y][snake.front().X] = 3; //原蛇头变为蛇身
snake.push_front(zz); //新增节点入栈
map[snake.front().Y][snake.front().X] = 2; //新增节点变为蛇头
if (snake.size() == 400) //蛇身节点超过400,游戏胜利
{
COORD coord; coord.X = 3; coord.Y = 8;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
cout << "游戏胜利!"<<endl;
Sleep(300);
break;
}
CreatFood(); //新建食物
}
else //下一步是空地
{
map[snake.front().Y][snake.front().X] = 3; //原先头部变为蛇身
snake.push_front(zz); //新增节点入栈
map[snake.front().Y][snake.front().X] = 2; //下一步变为蛇头
map[snake.back().Y][snake.back().X] = 0; //原蛇尾变为空地
snake.pop_back(); //蛇尾出栈
}
system("cls");
Draw();
}
}
main :
#include<iostream>
using namespace std;
#include"Game.h"
int main()
{
srand(time(NULL)); //获取随机种子
Game game;
game.Start();
return 0;
}
三,实际效果
项目目录
游戏整体界面
游戏失败界面