Blog

Keep up to date with the latest news

用C语言在windows环境下实现贪吃蛇游戏

1. 要实现这个游戏,需要相关知识:链表,函数,预处理指令,指针,结构体,枚举,动态内存管理,win32api

2. 实现游戏前提:打开命令提示符或者vs2022控制台

点上方 倒三角再再点击 设置

接着在默认终端应用选择 Windows控制台主机

另外,需要陌生的win32api知识,请自行了解:COORD 结构 - Windows Console | Microsoft Learn

GetStdHandle 函数 - Windows Console | Microsoft Learn

GetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

SetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

SetConsoleCursorPosition 函数 - Windows Console | Microsoft Learn

GetAsyncKeyState 函数 (winuser.h) - Win32 apps | Microsoft Learn

3. 游戏代码实现思路

5. 我们在一个项目里需要3个文件,分别是test.c(功能测试文件), snake.c(功能实现文件), snake.h(函数声明与预处理文件)

这里有我们用到的所有的预处理指令

6. 实现GameStart函数

6.1 我们要对蛇身以及贪吃蛇游戏的初始化状态(蛇头,食物,方向,游戏状态,食物权重,总分,蛇速度)进行设置,为了方便后期维护,这里将游戏初始化状态封装成整个对象

6.2 GameStart函数实现逻辑,注意,这个函数实现需要的参数一点是指针,否则只是传值调用,游戏就出会BUG

6.2.1 先封装一个SetPos函数来定位光标位置然后打印欢迎界面,同样是使用系统命令行指令来完成游戏界面的切换

6.2.2紧接着跳过前面的欢迎界面来到游戏地图,在创建地图时,因为我们提前设置了控制台长100宽30,所以将墙体长宽控制在合适范围,如我这里就控制在长58,宽27,这里打印墙体使用的特殊符号占据两个字母的宽度,因此这里x坐标要<29

6.2.3 初始化蛇身以及游戏相关状态,这里初始化蛇身采用单向链表头插法,而且这个蛇生成的位置是固定的,并且有一点要注意的,因为一个节点宽度时2,食物宽度也是2,墙体也是2,所以cur->x每次加2

6.2.4 打印函数实现,这里通过rand函数结合do while循环使得food_x绝对是偶数并且通过while循环排除了食物生成和蛇身重叠的情况

6.3 游戏运行函数的实现

6.3.1 首先打印在地图右侧打印帮助信息,再定位坐标打印食物分数和总分数,然后通过按键检测修改游戏相关状态,然后SnakeMove函数是蛇移动的关键,通过Sleep函数让蛇一步一步走,用来控制蛇的速度,Sleep时间越短,蛇的速度越快,最后以一个do while循环是这个程序只要运行状态一直是OK情况下能够实现蛇移动

补充一点:Sleep函数放在SnakeMove函数后面是为了防止按键延迟

6.3.2 打印帮助信息,下面是一个封装后的暂停函数,采用无限循环形式让程序只要操作者按了Space后一直处于暂停状态,直到再按一次Space后解除暂停

6.3.3 蛇移动函数的实现

6.3.3.1 NextIsFood函数判断蛇运动下一个坐标是不是食物,如果是食物,思路为头插尾不删,并且ps->_pFood和pnn重合了,要释放掉第一个节点,不要忘了总分增加,并且食物已经被吃了要再创建个新食物

6.3.3.2 如果前方没食物就需要采用头插尾删的策略,图示其实这个while循环并没有重新打印一边倒数第二个节点,但由于前面打印的蛇身没有被覆盖掉,所以后面第一个定位可有可无

6.3.3.3 这里考虑撞墙以及撞到自己其中撞到自己一定要从第二个节点开始遍历,否则第一次遍历时就会结束程序

6.4 游戏结束函数实现

7. 最后附上函数声明代码,测试代码以及运行图