程序设计的过程中,面对复杂项目,利用模块化思维分解任务,是关键的一步。读者一定要掌握模块化思维设计思维,为将来团队合作、协同完成大型应用软件做好准备。
01、“贪吃蛇”游戏
有了游戏框架之后,按照游戏框架完成“贪吃蛇”游戏。
“贪吃蛇”游戏角色有两个:“贪吃蛇”和“蛋”。也就是每幅图像都需要包含这两个角色。完成游戏的第一步,找到合适的数据结构存储游戏角色,显示在屏幕上。“贪吃蛇”的信息由一个较大的数组保存。
选择好合适的数据结构,则可以完成游戏元素的显示。
保存“蛋”位置的变量为:
int foodRow,foodCol;
保存“贪吃蛇”的数据变量为:
int snakeRows[100],snakeCols[100];
完成了最重要的第一步,接下来就按照框架流程来进行,每一个角色都包含着相同流程:初始化数据→显示数据→更新数据,如图6.6所示。
■ 图6.6“贪吃蛇”游戏框架图
(1) 初始化数据。
“食物”的位置是随机的,代码如下:
(2) 显示数据。
初始化数据之后,根据数据显示“蛋”和“贪吃蛇”的代码如下:
(3) 更新数据。
完成了“初始化数据”和“显示数据”两部分,剩下就是“更新数据”部分。
数据会发生变化的情况包括如下两种情况。
第一种:“贪吃蛇”的运动导致“贪吃蛇”位置信息发生变化;
第二种:“贪吃蛇”吃到“食物”时,“贪吃蛇”的长度会发生变化,会产生新的“食物”,“食物”的位置信息会发生变化。
“贪吃蛇”运动数据更新的代码如下:
当“贪吃蛇”吃到“食物”时,“贪吃蛇”和“食物”数据都要发生变化。是否吃到“食物”,这个模块的判决条件非常简单,就是“蛇头”运动到“食物”的位置,对应的代码如下:
完整的代码如下:
运行代码,游戏能实现“贪吃蛇”的基本功能,此时还差最后一步——“贪吃蛇”撞到墙壁或者自己时游戏结束,感兴趣的读者可以自己尝试完成该功能。
完成较为完整的游戏之后,发现程序设计其实就像搭积木一样,按照框架,将不同组件安装起来。
# 02、“打砖块”游戏
为了进一步感受“框架”的作用,不妨再完成一个经典的游戏:“打砖块”游戏。“这款游戏由苹果公司的创始人乔布斯和沃兹尼亚设计。从这款游戏中可以体验到乔布斯的“至繁归于至简”的设计思想。它的玩法非常简单:通过方向键控制底部的球拍左右运动,让小球通过不断反弹消除砖块,同时要保持小球不掉落。消掉的砖块越多,分数也就越高,如图6.7所示。
■ 图6.7“打砖块”游戏示意图
根据“贪吃蛇”游戏的经验,游戏中总共有3个角色:球、球拍和砖墙。每一个角色都需要找到合适的数据结构保存信息。球拍与“贪吃蛇”非常相似,可以使用一维数组去保存球拍组成的每个小方块的位置信息,然后根据位置信息显示出来。球与“食物”非常相似,使用单个变量就能保存位置信息,而顶部的砖墙则使用二维数组保存。找到合适的数据类型存储数据之后,按照游戏的框架,对每一个游戏元素进行初始化数据→显示数据→更新数据,直到完成游戏,如图6.8所示。
■ 图6.8“打砖块”游戏框架图
(1) 初始化数据。
根据图6.7所示,确定游戏角色的初始位置,初始化数据的代码如下:
(2) 显示数据。
完成了数据的初始化,接着就是将数据显示在屏幕上,代码如下:
(3) 更新数据。
接下来完成的是球拍在按键的控制下,朝着某个方向运动。球拍的运动与“俄罗斯方块”运动相似,都是整体运动,代码如下:
球拍在按键的控制下沿着某个方向运动。不过,当球拍运动到边界时,球拍还会继续运动,引发错误,所以需要一个判断球拍是否到达了边界的函数:
如果向左运动,则球拍的最左端运动到第0列,不能继续向左运动。
如果向右运动,则球拍的最右端运动到第7列,不能继续向右运动。
根据上面的分析,代码如下:
球拍完成之后,接下来完成小球的运动,球运动时遇到障碍就反弹,如图6.9所示。
■ 图6.9球反弹示意图
在第2章的案例中已经实现了球的反弹运动,定义两个变量表示小球运动方向:
int v;
int h;
变量v存储水平运动方向的值,值为-1时,表示向左运动;值为1时,表示向右运动。 变量h存储垂直运动方向的值,值为-1时,表示向上运动;值为1时,表示向下运动。 当球运行到左右两边的边界时,球水平方向会反弹,对应的代码为:
v =-v;
当球运行到上下界面,或者遇到了球拍时会发生垂直反弹,对应的代码为:
h =-h;
根据上述情况,球运动的代码如下:
完成了球拍和球的部分,还差最后一部分:砖块伴随着球不断运动,被击中界面不断动态变化,如图6.10所示。
■ 图6.10球运动方向示意图
接下来需要完成当运动的球击中砖块之后产生的影响。当球击中砖块时,砖块消失。所以,也就是球运动过的位置,如果对应的位置有砖块,则将对应位置的数组元素赋值为0,代码如下:
更新数据的代码为:
游戏完整的代码如下:
通过已经完成的“贪吃蛇”和“打砖块”游戏,可以体会到按照游戏框架逐步完成小游戏,就像通过流水线生成产品一样。
如果完成一个新的小游戏,则设计步骤如下。
(1) 根据游戏规则,统计游戏画面中会出现的游戏角色。然后根据游戏角色的特征选择合适的数据类型保存数据,通常有变量、一维数组、二维数组。
(2) 根据这些角色在屏幕上最初的位置,对每一个角色的数据进行初始化。
(3) 根据数据,将每一个角色显示在屏幕上。
(4) 根据游戏规则,更新每一个角色的数据,形成新的画面。