C语言实战——“贪吃蛇”游戏
# 01、综合案例
“贪吃蛇”是一款非常经典的休闲益智类游戏,玩法非常简单,通过上、下、左、右键控制蛇的运动方向,使蛇可以吃到食物。吃到食物之后,蛇会变得越来越长,如果撞上自己的身体或者墙壁,游戏就结束。这款游戏有几十年的历史,在此期间,衍生了各种版本,如增加多人对战模式、障碍物等新型玩法。
■ 图5.12“贪吃蛇”游戏示意图
本章需要完成的版本非常简单,按键控制“贪吃蛇”上、下、左、右运动,当“贪吃蛇”吃到食物时,身体会变得越来越长。如图5.12所示,上面4个小方块构成的是“贪吃蛇”,中间单独的方块是“食物”。
- 初始化数据
“贪吃蛇”游戏主要包含两个重要角色:“贪吃蛇”和“蛋”。完成游戏的第一步,需要找到合适的数据类型存储游戏元素。“贪吃蛇”由一组方块组成,可以使用一维数组来存储“贪吃蛇”的位置信息。简易版的“贪吃蛇”游戏,假定每次屏幕上只出现一个“蛋”,所以只需要单个变量就能存储“蛋”的位置信息。
“贪吃蛇”吃到“蛋”之后,身体会变长,而数组一旦定义之后,长度就固定了,那有没有可变长的数组呢?C语言在新的C99标准中支持“可变长数组”,但是很多编译器暂时不支持C99标准。不妨先将问题简化处理,先定义一个空间较大的数组,就像平时做预算时,把额度定得大一些,留下空间以备不时之需。同理,最开始时,将数组的大小设置大一些,留下足够的空间,应付不断变长的“贪吃蛇”。
选择好了合适的数据类型,就可以定义合适的数据类型保存数据。
保存“蛋”位置的变量为:
保存“贪吃蛇”的数据数组为:
另外,还需要变量记录贪吃蛇的长度,初始长度为4:- 显示“贪吃蛇”
初始化数据之后,根据数据信息,可以将“贪吃蛇”“蛋”显示在屏幕上,代码如下:
编译并运行代码, “贪吃蛇”和“蛋”显示在屏幕上。 - 按键控制“贪吃蛇”运动方向
接下来实现按键W、S、A、D控制“贪吃蛇”上、下、左、右运动。例5.3中实现的“贪吃蛇”游戏与经典版的“贪吃蛇”游戏有一点点区别,经典版中的游戏中,“贪吃蛇”一直沿着某个方向运动,按键按下改变其运动方向。这个问题很容易就能解决,需要使用到项目提供的getKey()函数,getKey()函数是在getch()函数的基础上加工而成的。它们之间的区别在于getch()函数是阻塞式函数,意思是这个函数不执行完,程序就一直停在这里,使用getch()函数时,必须按下任意键,才能执行后面的程序。getKey()函数是非阻塞式函数,如果想实现经典版“贪吃蛇”运动模式,就需要改用项目提供的getKey()函数。解决方法是定义一个变量记录“贪吃蛇”运动的方向,分别使用1、2、3、4代表方向上、下、左、右,如果有方向键按下,“贪吃蛇”的运动方向根据按键发生变化,否则就按原方向继续运动,代码如下:
编译并运行代码,“贪吃蛇”会一直沿着某个方向运动,除非通过按键改变运动方向。如果贪吃蛇运动到屏幕的边界,即将要出界,该如何处理?读者可以尝试完善程序,解决这个问题。
- 显示“贪吃蛇”
完成了通过按键控制“贪吃蛇”运动方向的任务之后,如果继续完成“贪吃蛇”吃到“蛋”变长的任务,容易出现错误。因为代码已经较为复杂了,继续再往上添加新的代码,可能产生错误,导致整个代码都无法运行。第6章将会讲解模块化程序设计,将程序分解成一个个独立的小模块,然后再将其组合成完整的项目。模块化的设计会降低程序设计的复杂度和难度,使得程序结构更清晰、层次更明确、更容易扩充、可维护性高。