每一位C语言初学者都渴望能够拥有一条属于自己的贪吃蛇。今天我们就来讲讲怎样才能把它收入囊中 o( ̄▽ ̄)o。
效果图呈上~
image好,接下来我们来捋一捋实现思路。
首先,整个游戏可以归为两大部分,静态页面和动态操作。
9693047-4e3847865e1a0b6c.png
静态页面包括初始页面、结束页面以及围墙的铺建,这些都比较容易实现,无非就是在特定位置输入不同颜色的文本和符号,其中,位置的确定需要借助Windows API中定义的一种结构,COORD,和控制台函数SetConsoleTextAttribute()。实例化如下:
image.png
懂了这个之后,大家就可以放飞灵感,创作出自己想要的页面了。
p.s. 值得注意地是,对于命令窗口而言,横向一个符号占两个字符宽度,纵向一个符号占一个字符宽度。
对于动态页面,主要分为蛇的构建、食物的构建、蛇的移动、以及游戏得分、移动速度等的设定。
蛇的构建,我们可以采用链表的方式,定义蛇尾指针(通过rand()函数随机生成,注意生成位置应位于围墙内),通过头插法构建一条“链表蛇”,再对该“链表蛇”进行遍历,从而实体化输出到屏幕上。
image.png
食物的构建就比较简单了,定义snake结构的food(因为要包含横纵坐标,且结构体方便进行操作),随机确定其出现的位置即可。需要注意的是,食物不能蛇身某节,否则需要重新生成。
image.png蛇和食物都有了,怎么让它动起来呢?
其实,蛇的移动过程可以通过更新链表位置,不断刷新原有蛇的轨迹来实现。GetAnsyncKeyState()函数可以获取虚拟键,即键盘操作。然后根据返回结果,去更新蛇下一时刻的位置。再通过Sleep()函数改变每次位置间的时间间隔,就能实现控制速度的蛇的移动了。
对于移动过程还需要分三种情况考虑,即蛇头下一刻的位置和食物重合,那么蛇应该吃到食物,蛇身增长,这时只需在蛇移动食物的前一刻插入食物的位置作为蛇的新的头指针,构建一条新的”链表蛇“,再打印出来即可。
第二种情况则是,蛇头下一刻的位置不与食物重合,即没吃到食物的情况。此时,头指针应由下一刻位置替代,而尾指针处只需打印背景图案后释放,就能保证蛇的长度不发生改变,只是位置移动了。
此外,还需要考虑以下几种特殊情况。移动过程中,蛇头碰到了围墙或者撞到了自己或者玩家想强制结束游戏(回到起始页面),那么就要分别对这三种情况进行判断,并调用endgame()函数跳转至结束页面。
具体代码实现如下:
image.png image.png
image.png
image.png
对于最后游戏得分、蛇的移动速度等的设定,通过建立相应的speedup()函数和score计分实现即可。
image.png
如果想要游戏运行流畅,更加完美,里面还有很多小细节值得注意。比如:控制台相同长度的x/y坐标所占字符宽度不同;每次游戏结束或者开始时需要通过123选择下一步的操作,就会有数字等字符保留在输入流中等等。
当处理好所有的细节后,给你的程序换个”赏心悦目“的icon,也会成为一个十分完美的好软件!O(∩_∩)O~~
网友评论