分享21级同学大一上学期用C语言(及少量C++)实现的坏蛋冰淇凌。由于同学们刚学了三个月的编程,实现还不够完善,工程代码、图片音乐素材可以从百度网盘下载:
链接:https://pan.baidu.com/s/1rNyHtjnLCG3ro-z24Yuktg
提取码:90lo
一、设计思路
我们通过main函数中的while循环不断更新游戏地图和关键参数的变化,同时在每次循环结束时进行清屏操作,实现实时刷新的效果。
由于游戏地图的特殊性(类似于棋盘一样具有界限分明的格子),我们采用了三维数组存储每关的地图,并为每一格都赋予了障碍属性和水果属性,为接下来由于玩家操作和关卡阶段推进导致的地形改变打下基础。玩家可以随意吐冰、破冰这种操作方式也让游戏有了更高的自由度、可玩性和操作性。
二、功能描述
Player 结构体存储人物的横纵坐标。
Monster 结构体存储怪物的横纵坐标。
函数功能:
startup函数 : 实现每个关卡内的重要数据,每个关卡的音乐,遍历怪物,人物的位置及初始朝向并将障碍数据存储于数组中。
fruitmove函数 :在后边的关卡中实现水果的随机移动,增加游戏难度。
show函数: 实现绘制功能,将地图对应的关卡,人物,怪物,水果进行绘制,及显示通关文字,失败提醒。
ICE 函数 :实现冰块的生成和消失,及生成、冰块破碎音效。
Move 函数:实现人物移动,未遇到障碍时按下相应的按键可以进行移动。
UpdateWithoutInput函数: 实怪物的移动、人物吃水果的音效、判定人物是否死亡、当前关卡任务是否完成。
UpdateWithInput 函数:获得用户按键的输入实现人物的移动方向及重新开始游戏。
三、分步骤实现方法
第一步:
实现该游戏的地图生成,利用二维数组将地图中的障碍,边缘数据存储起来,再将地图进行绘制,其中比较困难的是地图中的各种障碍不同,我们需要将其分别进行存储,为后边的人物、怪物的移动、吐冰及破冰的判定做好铺垫。
第二步:
实现人物随按键输入的移动及遇到障碍的判定,其中的难点在于人物对障碍的判定。不同于一般游戏,我们不仅设定了人物移动方向,同时引入了人物面部朝向(这对后续的吐冰破冰的代码有帮助),我们先判定人物朝向的前方是否有之前存储的障碍,若没有才能进行移动,而人物的坐标是一个点,我们的障碍是一个方块,所以我们将人物的坐标转换成了方块的坐标,再与之前的存储数据进行判断,才实现人物遇到障碍的判定。
第三步:
实现人物的吐冰、破冰功能,人物的吐冰破冰关键是判断其朝向的前方是否是空地或冰块及判定下一步是否继续进行此操作(我们人物生成的冰块前方有空地会一直生成,破冰是前方有冰块都会破掉),将新生成的冰块记录为障碍存储起来,其吐冰前方必须为空地,破冰前方必须有冰块。
第四步:
人物、冰块、水果图像的导入及冰块封住水果的障碍(我们的水果可以被我们生成的冰封住,处于无法吃掉的状态)数据记录,其难点是被封住的水果在人物进行破冰时,它不会消失,我们将冰封的水果数据进行记录,当破冰时遇到冰封的水果,让其变成原来的水果。
第五步:
在完成上述步骤后,我们向童晶老师征询了修改意见,童晶老师认为:我们的代码存在重复与繁琐的问题,虽然在先前的编程过程中,我们已经尽量提升了代码的可调试性,但在一番讨论后,我们一致认为现在的代码仍然存在较大的提升空间,不利于接下来功能的添加,也不利于契合先前的功能。
最终,我们决定对代码的底层结构进行重构。重构后的代码不论在逻辑、效果,还是在可读性上都有了飞跃般的提升,为接下来进一步的完善打下了坚实的基础。
第六步:
为了实现startup函数能自动检测每关的目标水果数,进而实现判定是否完成一关的效果,我们在startup函数中加入了自动存储每关每阶段目标水果数的代码。在本步骤的实现过程中,我们发现存在玩家在游戏第一阶段进行吐冰操作导致留下的冰块与第二阶段在地图上新出现水果冲突的问题,便在show函数添加了能通过检测目标格是否存在障碍类型的地形而判断新生成水果的状态的代码。
第七步:
我们实现了人物在格与格之间丝滑移动的功能。参考了老师推箱子的代码,我们在一开始将人物移动的效果实现成了从一格闪现到另一格。但考虑到这不利于接下来实现碰撞的功能,于是我们增加了能让人物从一格匀速平移到相邻格的代码,并保证在移动期间人物无法执行其他操作,直到人物就位。
第八步:
我们仿照了人物的移动,添加了不需要玩家操控的怪物的移动代码,同时实现了令其碰到障碍格就返回的功能和具有杀死玩家的能力(主要代码此处略,参考第七步)。
第九步:
最后,我们完善了游戏相关的音乐,包括吐冰、破冰、吃水果和通关的特效音乐,每关不同的背景音乐(根据关卡的推进,音乐的风格也会不断改变),以及人物死亡时的凄惨氛围音乐,这大大提高了游戏的乐趣。在这之后,我们又新增了几个有挑战性的关卡与彩蛋。在小组成员近2个月努力下,得到了现在的最终版本。
四、体会与总结
通过了本次课程设计我体会到了编写代码的不容易,认识到了自己的不足之处,在之后的学习中要弥补自己的不足,同时也收获颇丰,尤其是在自己写的代码能够实现自己想要的功能时会有一种成就感,原来在自己看来很容易的功能实现起来是那么的困难,让我知道了我们必须要自己动手去做事情才能够得到经验,不然就会像古代的赵括一样纸上谈兵,‘实践是检验真理的唯一标准’,在书上看到的东西,自己去亲身实践体会才会深刻,还有更重要的是我们必须要有自学的能力,没有人会教自己一辈子,但是自己可以教自己,在遇到不会的问题,不会的方法,我们都可以通过看书、上网、问同学、问老师借鉴先人的经验,就能得到很好的解决方法,牛顿说过‘如果我比别人看得更远些,那是因为我站在巨人的肩膀上’如这次在实现一些功能时,一时没有头绪,我就反复的观看老师的游戏代码,借鉴其代码结构、功能效果进行编写。
正如古人言‘欲速则不达’在我们编写代码时不要想着一口气吃成一个胖子,必须要好好的分步骤进行,先把基础的功能做好了再添加其它的功能,当然我们做其他事也应如此,不能急于求成,要一步一个脚印。