C++基于EasyX制作贪吃蛇游戏(一)文档
本文最后更新于:2019年11月14日 晚上
很早就想制作一个贪吃蛇游戏,老是写了一点就半途而废,终于狠下心来花了半天的时间写完了第一版本的贪吃蛇游戏,虽然因为坐标设置的原因导致有些小失败,但依旧完成了主要的功能模块,记录一下。
前提:EasyX
EasyX 是针对 C++ 的图形库,可以帮助 C 语言初学者快速上手图形和游戏编程。
官网链接:https://easyx.cn/
制作流程
先开始写文档,分析要实现哪些功能,然后对功能进行细分,梳理操作。以下80%的内容都是当时写贪吃蛇的文档,后期整理一下发博客记录。
草稿:想要实现的功能
贪吃蛇游戏的简单版本实现
- 贪吃蛇吃食物身体加长
- 食物被吃后随机出现(不能够出现在蛇的身上)
- 无操作时贪吃蛇自动向蛇头方向前进
- 上下左右移动位置
- 撞到身体或者墙壁死亡
- 显示时间与分数
功能梳理
蛇的操作
- 上下左右四个按键控制蛇头的朝向。当按键方向与蛇头方向相同或者相反时无反应。
- 不受操作时蛇自动按照蛇头方向前行
- 蛇头吃到食物之后,身体加长
- 蛇头撞到自身或者墙壁后死亡
- 蛇头控制方向,其余结点均是复制前一个结点的坐标。
食物的操作
- 初始时刻食物出现在某个固定位置
- 食物被吃掉后随机出现在其他地方,但是不能够出现在蛇的身上。
界面显示
- 分为游戏区与功能区,游戏区展现蛇与食物,功能区展示时间、分数、玩法介绍以及作者信息
- 蛇使用方块表示,蛇头与蛇身容易区分。食物使用圆形表示。
- 游戏结束后,显示“GAME OVER”,然后显示游戏时长以及游戏分数。
界面大小设置
- 坐标系。这是一个纯2D游戏,一般来说坐标都是在最左上角,为了便于计算(个人习惯),将坐标原点放置在左下角,x轴向右,y轴向上。
实际上游戏的坐标都是采用原点在左上角,这里因为我设置了坐标轴的原因导致了后面文字摆放无法放置正确,也是因为这个原因,要重写了第二版代码。
- 整体界面大小为:长640px,宽480px。游戏区为 480 * 480的正方形区域,位居界面左侧。功能区为 160 * 480的区域,位居界面右侧。
- 游戏区全部分为20 * 20 px的小正方形区域,便于蛇与食物的放置即坐标计算。蛇使用方块,食物使用圆形。采取图形中心点代表整个图形的方式,即(10,10)表示一个图形。为了防止边界的图像颜色干扰,设置蛇的方块中心点到四边的距离为9px,食物的半径为8px。
变量结构设置
食物结构体设置
对于食物而言,一次只会出现一个食物,只需要保存它的坐标位置,以及存在状态即可。
1 |
|
蛇结构体设置
对于蛇而言,蛇是由一个个节点构成的,每吃一个食物就会增加一个节点。并且所有节点都连接起来,采用链表是一个不错的选择。
结构体设置模仿自严蔚敏老师的数据结构链表的设置。定义蛇节点结构体,然后定义蛇的结构体。
本来采用的单向链表,但后续处理蛇的移动算法时发现需要从后向前复制节点的操作,于是改成了双向链表。
这里也可以采用数组啦,STL的vector容器啦来处理蛇的结构体。采用链表复习复习数据结构。
1 |
|
游戏核心算法
蛇身移动算法
贪吃蛇的移动完全是复制头部节点,蛇头控制方向与前进,其他节点均是重复前一个节点的行为。
而在处理蛇移动的时候,先要用后面节点的保存了它的前一个节点的坐标信息。故蛇身移动的算法,是从最后一个节点(tail)向前复制前一个节点的坐标,达成移动效果。
想到这里就把蛇的结构体改为双向链表。便于我的操作。
1 |
|
食物生成算法
食物生成要具有随机性,并且要求食物不能够生成在蛇的身体上。
随机数函数rand()产生随机数,rand()函数需要的头文件是:<stdlib.h>。
rand()会返回一个范围在0到RAND_MAX(32767)之间的伪随机数(整数)。
在调用rand()函数之前,可以使用srand()函数设置随机数种子,如果没有设置随机数种子,rand()函数在调用时,自动设计随机数种子为1。随机种子相同,每次产生的随机数也会相同。
srand( usigned int seed)函数用来设置rand()产生随机数时的随机数种子。参数seed是整数,通常可以利用time(0)的返回值作为seed。srand()函数需要的头文件是:<stdlib.h>
例如:生成0-6之间的任意一个随机数
srand(time(0));
int num = (rand()%7)//模求余
食物不能够在蛇的身体上,即生成坐标之后遍历蛇的节点进行匹配,若有对应的就直接重新生成一次。
1 |
|
按键处理问题
_khbit()
函数用来检测是否有键盘输入。如果有按键被按下,会返回一个1,否则返回值为0.它是一个非阻塞函数,无论有没有按键被按下,他都会立即返回结果。可以用来做循环的条件判断是否有按键,或者等待输入。
_getch()
函数作用是从控制台获取输入的字符,并返回获取到的字符值。而且这个函数是阻塞性函数,必须要获取输入字符后才会返回。
_kbhit()
与_getch()
都是位于conio.h
头文件中。(console IO)
1 |
|
由此可以测的我们按键对应的键值是多少。
方向键↑ 对应值为72。
方向键↓ 对应值为80。
方向键← 对应值为75。
方向键→ 对应值为77。
但是相信执行这一段代码会发现按一次键会有两个key被打印出来。但是写switch语句(代码中的按键处理模块)时却完全和第一个key值无关。这个问题暂时还没有解决!路过的大佬欢迎留言~
这个方法我是从某潭某州的公开广告课上学到的。
其他参考链接:C++中_kbhit()函数与_getch()函数
伪流程
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!