1.设计题目与要求
设计一个小型的电脑游戏
用自己熟悉的程序设计语言编写一些简单的游戏。
要求:诚信为本,自己学习设计电脑游戏,不允许直接从网上下载现成的游戏代码如俄罗斯方块、贪吃蛇、五子棋、推箱子游戏等作为自己的设计,但可以对这些下载下来的游戏进行改进,提交报告时需说明自己改进的地方并写在设计报告中,否则成绩记为零分。
2. 设计软硬件环境
windows10 64位操作系统
Visual Stdio 2017 编译
3.功能设计与描述
(描述设计系统所具有的功能,以及相关算法设计和实现过程等,要求画流)
坦克大战小游戏,一共八关。不同的关卡,游戏地图、敌方坦克出现的种类不一样。敌方坦克地图上最多存在4辆,击杀后会出现新坦克直至补足4个,当击杀坦克一定数值则敌方新坦克不会再增加。击杀完所有坦克则胜利过关。己方坦克也有复活次数,用完则失败。另地图正下方有己方老家,若被敌方坦克攻破则游戏失败。
整个程序分为里表两大部分。
里部分由41*41的int地图数组组成,每个元素代表了该以该数组元素行列下标为地图坐标y,x那个单元的情况,不同的地图障碍物在该数组有不同的值,坦克在地图上占3*3个单元,在地图数组内相应坐标的3*3个元素内也对应特殊的值。由地图数组值可以读出该坦克信息。
表部分则是根据里部分的地图数组通过gotoxy和printf函数在命令行界面打印出相应字符以构成游戏界面的。
程序中的每个函数操作都是通过里部分(地图数组)判定,然后对里部分(地图数组)操作,再由里部改变外部,由gotoxy和printf函数将可视化界面呈现给玩家。
也就是游戏主体函数内里表部分是一起操作的,不分开。
对于函数分类,程序又可分为三大类。一类游戏辅助函数。一个子弹系统,一个坦克系统。子弹和坦克分别都是独立运作的系统,有少量信息交换。
子弹系统
子弹在地图数组内没有值,但每颗子弹记录了子弹坐标(对应地图数组的坐标),子弹发射者等信息,由子弹坐标对应地图数组坐标中的数组值判定子弹碰撞障碍物或判定击中坦克等,再产生不同的响应。
子弹结构体为长度20的数组,一个元素代表一颗子弹。坦克部分发射子弹函数执行,则按顺序激活一颗子弹(改变子弹的一个标记),若激活的子弹为子弹数组[19]。则下一个激活[0],并改变给子弹的其他值。子弹击中物体后既被灭活(改变标记)。
子弹移动函数只执行被激活的所有子弹,执行子弹移动,碰撞判断与碰撞事件等。也就是说,子弹一被建立就是自己”飞”了,相当于将子弹交给了移动函数执行。两个部分有类似面向对象的概念。
坦克系统:
我方坦克样式:被子弹击中则死亡,颜色天蓝色,速度为子弹速度的1/2
敌方坦克分三种:
普通坦克:被子弹击中则死亡,颜色随机产生, 速度为子弹速度的1/3
血量较高的坦克:,初始为绿色,被子弹击中一次变黄,其次变红,再次被击中则坦克死亡。速度为子弹速度1/3
速度较快的坦克:被子弹击中则死亡,颜色随机,速度为子弹速度的1/2
每次坦克移动先抹去地图数组中3*3个元素的值并抹去显示的坦克图案,再由传入的移动方向在下一个3*3方格内重新给地图数组赋值并在界面打印图案。坦克碰撞由读取坦克前方1*3的地图数组值完成。
地图部分:地图边界为子弹击中则子弹消失的方块。地图内的障碍物分四种,两种不同颜色的▓(砖块),子弹击中则消除与子弹移动方向垂直线上的三个方块(若子弹为纵向则消除子弹击中处、子弹击中处相邻左右共三个方块),若左/右方块不为▓(为其他障碍或没有障碍)则不处理。
AI部分:
AI坦克移动:
一定几率执行方向重置(转向或不变),后原地停止一定时间。(大部分时间还是会直线移动),遇到障碍一定几率选择出有通路的方向,一定几率方向重置(乱转),乱转后原地停止一定时间。之所以设置方向重置是因为地图原因,AI需要偶尔往一个方向发射子弹打碎砖块以开辟新通路,也为玩家的预判增加不确定性,增加游戏难度。让AI坦克停止为了凑足子弹冷却时间,让AI坦克向此方向发射子弹。
AI子弹发射:
一般情况下CD(冷却时间)超过一定数值则一定几率发射子弹(若随机判断为不执行,则下一次循环依然再执行随机判断,此时CD一直不变),一旦发射,CD重新计时。若敌方坦克通过它的坦克方向正好能击中我的坦克且CD达到一定值(比一般情况下的值要小),则立即发射子弹。由于地图原因,敌方99%的可能都会从最下一行的通道发射子弹攻破老家。所以当敌方坦克处于最下一行并且坦克方向朝向老家,也如上CD达到一定值后直接发射子弹。AI发射稍强化了AI以调节游戏平衡。
另:(关于程序主函数死循环体执行方式)
原本坦克子弹发射冷却时间、子弹运动都由子线程完成,后学习了在主线程死循环中添加计数器来实现多线程的功能后就弃用了多线程,方式类似于单核cpu的多线程实现,就是单线程程序在不同操作间来回跑以达到多线程的效果。这样还可以更方便实现游戏内置调节游戏速度的功能。如死循环中固定每次循环Sleep(5); 于是添加判断interval[0]++%speed==0,为真则执行真正循环体。当speed为1则每次循环都会执行所有真正循环体中的操作,相当于每次循环间隔5ms。speed为3则3次循环执行一次,相当于每次循环间隔15ms,达到游戏速度的微调目的。
而体现出子弹和坦克间的速度差也是同理。子弹中添加计数器,每次执行上述真正循环体时自增,当计数器为某数的倍数则执行子弹移动。坦克移动函数也有计数器每次自增,当计数器为某数的倍数则执行坦克移动。
而该程序由于子弹已经为最小单位的时间,既每次循环都执行,于是没必要设置计数器。而坦克的interval++%2==0判断则是上面描述的实现,于是子弹速度为该坦克速度的两倍。既每次循环都会执行一次子弹移动,而需要两次循环才会执行一次坦克移动,就体现了速度差,也省去了多线程。
5.程序运行结果
6.设计总结
游戏分里外两个部分组成,里部分(用户不可见) 通过里部分执行判断,地图数组更改,和各种值的改变。更改完里部分再根据相应变化更改表部分。(用户可视部分)表部分的打印通过gotoxy去到相应坐标再printf打印出字符,通过文本函数改变文字字体颜色与文字背景颜色与字符组合实现图形界面。
程序通过 计数器+循环判断 的思想,类似单核cpu的多线程实现(单线程在不同程序/函数间来回执行)省去了多线程。(具体过程在功能设计与描述有详细描述)
另AI实现与加强依赖于rand随机函数的运用,进一步强化AI,增加游戏乐趣
功能方面,游戏参考于80年代任天堂红白机(FC/FamilyComputer)上的游戏坦克大战(Battle City),包括地图,游戏模式等等(当时的游戏直接烧在电路板上)。所以游戏平衡方面已经有了很好的参考,无需再花大量时间测试平衡性。
但诸如地图中的树林元素,随机道具等没有实现。但较之原版,该游戏由C/C++编写PC运行,由字符界面实现游戏画面。原版一辆坦克的子弹未消失之前不能发射第二颗。导致子弹打击远处CD长,近处CD短。该游戏每个子弹都有相同CD,子弹未消失只要CD达到即可发射第二颗,第三颗…增加了真实性,相较于原版是个改进。且考虑到PC性能不一内置了游戏速度调整。玩家可根据PC性能调整至合适的速度。
下载链接:https://download.csdn.net/download/weixin_41098116/11079280