在有用C写贪吃蛇的一个想法之后,上网查了几个教程,觉得不是很能看懂。恩。。。或者说不是一下子就能看出来思路+具体怎么实现。所以,我花了早自习的时间想了想如何用最简单的方法实现,晚上大约两个小时写了出来。别说我用两小时装逼,有了思路之后就是码代码和查细节的问题。
PS:这里补充说一下C语言写的控制台游戏的原理是什么,知道的同学直接跳过这一段。实际上就是不断的用system("cls");
清除屏幕再重新打印不一样的内容,在速度较快的时候就会有一种动画效果了,当然这是控制台,就没法究美观了(可以改一下控制台字体和背景颜色相对好看一点,具体百度),晃眼睛也是肯定的。
如图(中间有一点空白gif抓取的时候没抓到请忽略):
源代码已经放在了github上感兴趣的可以参考一下(顺便star一下看官们)
** C-snake-iimT **
我们开始说思路。
- 我们需要一张地图,中间是空的四周有墙体。
- 我们需要一条蛇,这条蛇由蛇头和蛇身组成。
- 我们需要食物,并且在蛇吃掉食物之后将蛇的身体变长,而且重新生成一个食物。
- 蛇需要移动,这应该是最难实现的。
- 蛇撞到墙或者撞到自己的身体就会死亡。
- 我们需要能用键盘控制蛇的运动方向,这个会和蛇的移动有一些联系。
Balabala我们有这么一大堆问题,我们来想想应该如何用代码实现。
-
整个地图我们用一个坐标系建立起来,这用一个二维字符数组就能实现了,然后我们的蛇和食物只需要将中间的空格改成蛇的头或者身体或者食物的样子就行了。
-
这条蛇应该如何描述,我们先区分蛇头和蛇的身体,然后一组坐标来将这个蛇的头、头后面第一节、第二节、第三节。。。。以此类推。我现在是2050的地图,所以我用一个
snake[1000][3]
来描述,这里面的1000是2050就是现在有1000个空(假如有人就玩到将整个地图霸占了呢)坐标,snake[i][0]
的值用来描述这个坐标是头·snake[i][0]=1
还是身体snake[i][0]=0
,然后snake[i][2] snake[i][2]
分别用来描述所在的X坐标和Y坐标(i表示某一节)。这样我们就用一个数组将蛇描述出来了,在后面我们生成视图的时候将该点的空格换成'#'或者'@'就好了。 -
生成食物我们需要产生随机数作为食物的坐标,而且这个随机数要在一定的范围内不能在围墙上,也不能和蛇的坐标一样。生成随机数用
srand(time(0));
int a = rand()%10+1;
这样我们就能得到1-10的数,这里的srand(time(0));
初始化一下时间函数,然后rand会给我们一个很大的秒数,这个秒数在不断的变化,%10之后得到的数就在0-9,然后+1得到1-10的数。根据这个原理,生成一个在固定范围内的X坐标和Y坐标,然后用这个x坐标和y坐标去遍历snake数组看看x、y会不会同时相同,如果相同就重新生成一个知道不相同为止。这样我们就生成了一个食物的坐标。
-
蛇的移动,就是不断的变化那个坐标集合,我们将蛇头移动到下一个坐标之后,后面的节一次覆盖前一个就完成了一个单位的移动。这样的话,我们的方向只需要对蛇头作用就行了。现在我们设定一个
direct=1
即向上,direct的值1/2/3/4分别代表上下左右。现在蛇向上走,蛇头向上的话,X不变,Y-1就好了。 (注意我们这里的坐标系是类似数学上第四象限的坐标系,所以X轴在最上面。) 然后我们将第二个节换成前一次蛇头所在的坐标,第三个坐标变成前一次第二个的坐标,以此类推,蛇就往前移动了一个单位。 -
蛇头撞到墙或者撞到自己的身体,我们只需要判断蛇头的坐标是否和墙的坐标重合或者和蛇的某一节重合。所以在蛇移动之后我们用蛇头的坐标去遍历蛇自己的所有坐标并且判断蛇的X或者Y是否大于或者小于地图边界了,这样就能知道是否发生碰撞,发生碰撞之后直接break不在刷新视图就好。
-
当键盘有输入的时候判断是上或者下后者左或者右,然后重置direct的值,就将方向重置了。当然在向上走的时候按下键是不行的其他也是类似,所以还要判断一下。键盘读入事件我们需要用到一个函数
_kbhit();
如果有键盘敲击,这个函数就会返回一个非0的数。所以我们可以在每一次刷新的时候
char ch;
if(_kbhit()) //有键盘敲击
{
ch = _getchar();
}
switch(ch)
{
//判断用户按下了哪个键
case 'H':
//按下键盘的上键_getchar()得到的是H
//可以自己写一个程序看看上下左右分别是哪几个字符然后用来判断就行了
if(direct!=2)
//如果当前的方向不是向下 就将方向重新定义为向上 其他的类似
direct=1;
}
这样我们就通过读取键盘重新设置了方向。
- 这些问题我们都一一解决了,现在我们来想一下程序运行的顺序是什么。
1)初始化,将地图造出来。
2)如果有键盘输入的话,就重新设置运动方向。
3)制造食物。
4)让蛇移动,如果吃掉食物就重新生成一个食物,如果会死亡就break。
5)用蛇的坐标将地图中的空格替换为'#'和'@',将食物所在的坐标设置为'O'。
6)输出视图,即将最终生成的地图打印出来。
7)Sleep(200) 暂停200毫秒之后在进行上面的。
我们将上面这些都放在一个while(1)
循环里面,只有死了才会跳出循环不在清屏打印(清屏打印其实就是刷新视图),然后输出游戏结束得分就好。