一,項目簡介
距上個項目(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;
}
三,實際效果
項目目錄
遊戲整體界面
遊戲失敗界面