C语言实战 | “贪吃蛇”游戏重构

举报
TiAmoZhang 发表于 2024/06/27 21:10:28 2024/06/27
【摘要】 程序设计的过程中,面对复杂项目,利用模块化思维分解任务,是关键的一步。读者一定要掌握模块化思维设计思维,为将来团队合作、协同完成大型应用软件做好准备。

程序设计的过程中,面对复杂项目,利用模块化思维分解任务,是关键的一步。读者一定要掌握模块化思维设计思维,为将来团队合作、协同完成大型应用软件做好准备。

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) 根据游戏规则,更新每一个角色的数据,形成新的画面。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。