基于C++飞机大战游戏的改进

文章详细描述了一个飞机射击游戏的完善过程,包括增加敌机种类和动态难度调整,使用面向对象编程优化代码结构,设计敌机类和链表管理,实现动态难度、波次攻击和UI界面改进,以及游戏测试效果。同时,文章提出了敌机和子弹的属性设定,以及游戏中的防御机制和中场维修功能。
【功能和性能完善目标】
  1. 增加敌机的种类,包括其发射的子弹类型、血量和攻击方式等,每个敌机都有随机分配的独特属性,子弹也有不同的性质。
  2. 动态难度:在用户选择难度的基础上,随着得分的增长难度也不断提高。游戏的难度体现在敌机速度、血量、数量、种类,以及敌方子弹射速和移速等等。
  3. 增加我方飞机的血量、装甲和护盾,在受不同种类子弹攻击时有不同的反馈。
  4. 防止玩家的飞机飞出边界、穿过敌机等不合理操作。
  5. 将敌军的攻击波次分开,每次击毁一定敌机数量后游戏暂停,可以对己方飞船进行简单维修。
  6. 在控制台的基础上完善UI设计,增加图鉴界面以帮助新手玩家;完善开始、难度选择、暂停、维修、结束等界面间的切换逻辑;在战场下方显示我方飞机的状态面板、总得分和本轮攻击进度条。
  7. 使用面向对象程序设计改进代码。
【完善思路】
  1. 创建敌机类,将每一个敌机视作对象的好处是可以赋予其独特的属性,如种类、血量、飞行速度、武器种类、子弹发射速度等。
  2. 设定敌机种类、子弹种类的枚举,与它们的底层数字对应起来,使用时只需关注它们的名称,使代码具有较高的可读性和维护性能。
  3. 设定用户选择难度、自动难度以及它们组合出来的总体难度的枚举,创建敌机对象时,它们的血量、飞行速度、发射速度、武器种类等属性要根据难度数值进行调整。自动难度要根据当前得分进行切换。
  4. 以链表存储敌机对象,以提高在添加/删除敌机时的性能,优化占用的内存空间。
  5. 创建变量存储当前已摧毁的敌机数量,根据当前难度决定本轮需要摧毁的敌机数量。当摧毁足够多敌机时就暂停游戏,玩家此时可以维修自己的飞船,进而继续作战。
  6. 使用txt文档配合输出语句构建较为美观和易懂的UI界面。
【工程文件结构】

Enemy类,用于创建和操作敌机对象,包含头文件和源文件

enList类,以链表方式存储和管理已创建的敌机对象,包含头文件和源文件

difficulty头文件及源文件,存储和动态难度相关的函数和变量

gamerunning.cpp,存储游戏一次刷新时需要被更新的函数

utils.cpp,不再存储敌机相关函数,新增了一些操作我方飞机的函数。

define.h,声明全局变量和全局函数

ui.cpp,存储和UI界面有关的函数

main.cpp,主函数。

源代码目录的ui文件夹下存储的txt文件用于快速构建UI界面。

工程名:Plane-Advance

【程序实现的简要过程】
  • 对Enemy类的编写
  1. 使用静态函数add创建敌机,并将构造新对象的所有步骤包装起来,最大程度简化调用时的代码。
  2. add函数中的setEnemy用于设定敌机的基本属性。应实现传入敌机种类后,在函数中(根据当前游戏难度)在一定范围内随机生成敌机的武器种类、血量、移动速度、子弹射速等属性,并存储在该对象中,返回指向该堆空间的指针。
  3. add函数中的setLocation用于设定当前敌机的位置,当这个位置有其它敌机或子弹(checkBoth)时,就再随机生成一次,直到生成成功。航空母舰的生成不进行这种判别,而是生成后将它覆盖的敌机对象全部删除。
  4. createEnemy用于把敌机对象的部件映射到二维数组中,这样就可以在下一次刷新时构建敌机的画面了。
  5. fire,move,hit,dispatchL/R等函数,用于执行敌机的各种动作。执行这些动作的频率是在对象内部写好的,调用时无需关心。
  6. 如果敌机在各种原因下可被删除了,则视其为可删除(deleteable)的。这个属性可被外界读取从而在链表中删掉这个对象。在敌机确认是被击毁后调用destroy,删除飞机在二维数组中的对应数字,这样一个敌机的销毁才完成。
  7. 敌机种类、敌方子弹(武器)种类多种多样,将它们设为不同整型值并设为枚举型,提高编程时的体验~

  • 对enList类的编写
  1. 链表结点的创建、删除和清空是静态函数,在函数中包装构造和析构过程,调用时无需关注内部实现。添加结点采用最简单的头插法,删除函数会自动遍历所有对象,找到deleteable时完成整个析构过程,并自动连接剩余链表。清空则是逐个删除敌机对象和结点。
  2. 在对各个敌机执行动作时,要获得指向各个敌机对象的指针。用iterate函数实现链表的逐个遍历,用check函数获取敌机对象的指针,然后可以调用不同的函数实现功能。
  3. 对外开放链表的头指针,作为遍历操作的入口。

  • 动态难度的实现
  1. 两个有关难度的文件负责的是全局难度的控制,以及在敌机类中无法控制的“受难度影响”的部分,同样使用枚举型使编码易读。
  2. setCurrentDifficulty根据当前分数、玩家选择的难度自动设定难度数值,在游戏运行过程中要频繁调用。
  3. 有关敌机:getType根据当前难度获取“允许出现的敌机种类”中的一个。getNum控制同屏敌机数量。setEnbFlyingSpeed控制敌方动能子弹移动速度。

  • 原有代码部分的改动
  1. 涉及到敌机操作(增、删、毁、发射子弹、移动)的部分从updateWithoutInput的循环遍历中移除,改为遍历每个对象。
  2. 在遍历二维数组的环节,由于不同种类子弹的移动方式不同,所以增加了对这些子弹移动的判别;同时也有这些子弹和我方子弹坐标重合后相互穿过的判别(详见代码)。
  3. 使用从下到上的方式遍历二维数组,好处是不同种类的敌机子弹能够正常移动,而我方子弹会遇到移动多次的问题。由于我方子弹只有一种,只需创建一个数组记录它们所有的坐标,然后在遍历完二维数组后一次性全部移动即可。这种方式相比两次相反方向的遍历提高了一些性能。
  4. utils中删除了关于敌机的部分。特别地,我方飞机不应该自由地“撞”上敌方飞机。于是,在用户输入-移动我方飞机的部分,增加了对应方向是否存在敌方单位的判别。如果是敌机/航母,则我方飞机不向对应方向移动;如果是子弹,应该扣除船体生命。
  5. show函数中增加相应判断语句,构建更多样的画面。

  • 新机制:波次攻击的实现
  1. 我方飞机的船体/装甲/护盾属性增加后,如果我方飞机受到攻击而得不到维修,将会很快被摧毁,致使游戏结束。这样,游戏难度将会大幅上升。为了进一步增加游戏可玩性,将敌机的攻击划分为了不同波次,两次攻击波之间可以维修我方飞机。
  2. 使用两个变量控制本次攻击波的总敌机数和已摧毁的敌机数,总敌机数是受到当前难度控制。添加两次攻击波之间的暂停界面,在该界面中可以选择护盾/装甲/船体中的一项进行修复。
  3. 每次中场暂停结束后,都重新初始化战场。

  • 构建UI界面
  1. 所有较为复杂的静态页面,都通过读入txt文件实现。
  2. 进度条,组合使用”=” , ”-”实现,当前进度由当前攻击波已摧毁的的敌机决定。

【游戏设定文稿】

关于敌方飞机/子弹的更多设定,参见游戏当中的“图鉴”。

护盾 --防御-- 能量武器:激光束,损伤整条路径的目标

装甲 --防御-- 动能炮弹:普通的子弹,分为单发、散射和三联发方式

装甲 --防御-- 导弹:可被击落,不仅能损伤飞机,也能损伤基地而减少总分

当相对应的防御值为零,这些武器就对船体生命造成损伤。

【测试效果】

1.打开游戏,自动设定合适的窗口大小。按m键进入图鉴,了解游戏设定。

 

2.在主界面按Enter进入选择难度的界面,按下对应按键后进入游戏。

(随着难度的增加,同屏飞机数增多,飞机移速加快,敌机子弹射速加快,子弹移速加快,飞机的血量变多,更高难度的飞机种类更早出现。)

 

右图是简单难度开局情况。战场下方是信息栏,可以动态显示我方飞机目前的状态、总得分和当前攻击波的进度。

下面是选择了不同难度后的开局情况。可以看到敌机的种类变得更加丰富,敌机的数量也变多了。

 

                           普通难度                                                              困难难度

3.随着本轮击落的敌机数量增多,进度条随之上涨。

 

4.多种多样的敌机。

散射式动能战斗机能对我放飞机造成较大威胁。

轰炸机发射的导弹能被击落,如果未被击落,则会对基地造成损伤。

能量战斗机发射的激光束对整条路径上的目标进行攻击。

航空母舰定期派遣随机样式的飞机,且无视场上飞机数量的限制。

 

5.中场休息:当击退一波攻击后,飞船返回基地检修。

每次可以选择一项防御值进行填充。这里按a键填充了飞船的装甲值。

 

6.分数增高到一定值,我方子弹会在基地检修后得到升级,以应对越来越多的敌机。敌机的生命值也会变得更高,被击中数次后才会被击落。

 

                           补充装甲值                                                           我方子弹升级

7.暂停功能与简单版本保持相同。选择退出后能显示最终得分。

 

                    我方子弹再次升级                                                         暂停

8.退出到主界面后,可以重新开始一局游戏。

 

【代码】

直接打开Visual Studio工程即可调试代码。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值