一,项目简介
1,游戏规则
(1)按键盘方向键控制蛇移动,每吃到一个食物蛇身就增长,并得到积分。吃到“超级食物”积分加倍。
(2)如果蛇头碰到边界或蛇自身,游戏结束。
(3)游戏过程玩家可按 Esc 键暂停游戏。
2,游戏难度
游戏按照蛇的移动速度分为4种难度。
3,游戏结果
玩家每玩一次游戏会有分数,并且可选择是否退出游戏。
4,项目运行环境
Visual Studio
二,项目分工
本项目由第三组同学完成。
1,写代码
谢**
2,修改程序
王**,洪**,田**
3,写报告
王**
4,讲解演示
谢**
三,程序结构
整个程序共有七个类,分别为Tools, Point, Start Interface, Snake, Map, Food, Controller。
1,Tools 类
Tools工具类主要是用于设置光标的位置以及输出文字的颜色。
void SetWindowSize(int cols, int lines);//设置窗口大小
void SetCursorPosition(const int x, const int y);//设置光标的位置
void SetColor(int colorID);//设置文字的颜色
void SetBackColor();//设置文字背景的颜色
2,Point 类
Point类设置点的对象。
在这个项目中,点是最基础的类,食物是一个点,蛇是由点组成的。
class Point
{
public:
Point() {}//构造函数
Point(const int x, const int y) : x(x), y(y) {}//有参构造函数
void Print();//打印方块的函数
void PrintCircular();//打印圆形的函数
void Clear();//清除点的函数
void ChangePosition(const int x, const int y);//改变点位置的函数
bool operator== (const Point& point) {
return (point.x == this->x) && (point.y == this->y);
}//函数重载,判断两个点是否相等
int GetX() { return this->x; }
int GetY() { return this->y; }//得到点的坐标
private:
int x, y;//点的坐标,
};
3,Food 类
Food类实现食物的随机出现。
class Food
{
public:
Food() : cnt(0), flash_flag(false), big_flag(false), x(0), y(0), big_x(0), big_y(0), progress_bar(0) {}//构造函数
void DrawFood(Snake&);//绘制食物的函数
void DrawBigFood(Snake&);//绘制超级食物的函数
int GetCnt();//得到食物出现的次数
void FlashBigFood();//闪烁超级食物的函数
bool GetBigFlag();//判断是否有超级食物
int GetProgressBar();//得到进度条的函数
private:
int cnt;//食物出现的次数
bool flash_flag;//闪烁标记
bool big_flag;//是否有限时食物标记
int x, y;//食物位置
int big_x, big_y;//超级食物的位置
int progress_bar;//限时食物进度条的长度
friend class Snake;//友元类
};
4,Map 类
Map类负责绘制地图。
class Map
{
public:
Map()//默认构造函数,将正方形各点压入initmap
{
//左右两边两条
for (int i = 1;i <= 30;i++) {
initmap.emplace_back(Point(i, 1));
initmap.emplace_back(Point(i, 30));
}
//上下两边两条
for (int i = 2;i <= 29;i++) {
initmap.emplace_back(Point(1, i));
initmap.emplace_back(Point(30, i));
}
}
void PrintInitmap();//绘制初始地图
private:
std::vector<Point> initmap;//保存初始地图
};
5,Snake 类
Snake类控制蛇的移动和吃到食物等。
/*
蛇由一个个点构成,用双端队列 deque 储存点
每吃到一个食物,就从头部添加,所以图像中蛇的头部是存储蛇数据的尾部
在这个程序中,蛇的头部就是snake.back()
*/
class Snake
{
public:
enum Direction { UP, DOWN, LEFT, RIGHT };//用枚举储存键盘信息
Snake() {
//设置蛇的初始长度,由三个点构成
snake.emplace_back(14, 8);
snake.emplace_back(15, 8);
snake.emplace_back(16, 8);
//设置蛇的初始方向,向下
direction = Direction::DOWN;
}
void InitSnake();//初始化蛇
void Move();//蛇增长
void NormalMove();//蛇正常移动,头增长,尾缩短
bool OverEdge();//超出边界
bool HitItself();//撞到自身
bool ChangeDirection();//改变方向
bool GetFood(const Food&);//吃到普通食物
bool GetBigFood(Food&);//吃到限时食物
private:
std::deque<Point> snake;//双端队列,储存蛇身
Direction direction;//蛇的方向
friend class Food;//将Food类置为友元,以便访问其私有元素
};
6,StartInterface 类
startinterface,游戏开始界面,包含了入场的动画。
class StartInterface
{
public:
void StartInterface() : speed(35); //游戏开始动画
void PrintFirst();//蛇从左边出现到完全出现的过程
void PrintSecond();//蛇从左向右移动的过程,用GPT写的,有一些数学逻辑
void PrintThird();//蛇从接触右边到消失的过程
void PrintText();//输出画面
void ClearText();//清除画面,实现动态效果
void Action();//总控制函数
private:
std::deque<Point> startsnake;//开始动画中的蛇
std::vector<Point> textsnake;//开始动画中的文字
int speed;//动画的速度
};
7,Controller 类
Controller类就是控制整个游戏过程的,包括游戏的各个阶段,比如更新分数,游戏难度选择等
class Controller
{
public:
Controller() : speed(200), key(1), score(0) {}
void Start();//开始界面,实现开场动画
void Select();//选择界面,选择难度
void DrawGame();//绘制游戏界面
int PlayGame();//游戏循环
void UpdateScore(const int&);//更新分数
void RewriteScore();//重绘分数
int Menu();//选择菜单
void Game();//游戏一级循环
int GameOver();//游戏结束界面
private:
int speed;//停留时间
int key;//选项
int score;//分数
};
8,Main
游戏入口
#include "controller.h"
int main()//程序入口
{
Controller c;//声明一个Controller类
c.Game();//整个游戏循环
return 0;
}
四,程序流程
1,进入游戏
通过 Main 函数进入游戏。
2,生成游戏控制类
生成一个 Controller 类,控制整个游戏。
3,生成游戏开始界面
通过 Start Interface 类输出游戏开始界面,列出游戏目录,玩家可选择难度
4,生成游戏地图
通过 Map 类生成地图。
5,生成蛇和食物
通过Snake类生成一条蛇。
通过Food 类随机生成食物。
6,控制游戏结束
通过Controller 类控制游戏是否结束和是否重新开始游戏。
五,运用的数据结构
1,面向对象编程
整个程序是严格地通过调用类方法运行的。
(1)基础类
Tools 类:工具类。
Point 类:构成蛇,食物,地图的最小单位。
(2)延申类
Map,Food,Snake 类:包含各自的方法和基础类。
Controller,StartInterface,Main 类:控制游戏的类。
2,双端队列
蛇由一个个点构成,用双端队列 deque 储存点;
每吃到一个食物,就从头部添加,所以图像中蛇的头部是存储蛇数据的尾部;
在这个程序中,蛇的头部就是snake.back();
3,链表
在开始界面的动画中,每一个点都按打印顺序储存在链表中。
六,程序不足
我们以正版的《贪吃蛇大作战》为参考

1,画面单调
因为没有使用其他适合做图形界面的框架,画面并不美观。
2,蛇的移动僵硬
只有上下左右四个方向,感觉很机械。
3,食物单一
每个时间段食物只有一个。
4,只有一条蛇
由于没有添加多线程处理,使得游戏只有一条蛇和一个食物。
七,项目开源
GitHub 地址
https://github.com/xiebaoma/GreedSnake
欢迎访问,下载,提交补丁。
如果你觉得还不错,麻烦给个 Start 。