python大作业:飞机大战分析与设计(大一pyhon程序设计)

发布于 2022-05-24  719 次阅读


python飞机大战,少许参考https://zhuanlan.zhihu.com/p/452322273,可能目录结构写得比较烂,请见谅。大一写的飞机大战可能之后回来看会觉得写的很恼火吧

项目代码请参考:python大作业:飞机大战代码

或者下载压缩包(含图片素材):飞机大战源码+图片素材.zip

pyinstaller打包后的可执行文件:飞机大战.zip(解压点击飞机大战.exe即可运行)

运行效果:飞机大战.mp4

分析:

  1. 创建游戏主窗口
  2. 创建游戏时钟来控制循环频率 达到动画效果
  3. 对游戏各个事件进行监听以及键盘输入的监听,达到攻击和释放技能的目的
  4. 自定义事件用以判断特殊事件的发生
  5. 通过碰撞检测判断敌机和玩家的血量
  6. 创建血条UI和分数显示
  7. 失败后跳入结束结算页面

游戏循环/分数检测

为完成整个游戏的循环,需要在主游戏循环外再建立一层循环,在game类中设定变量Begin判断是否进入游戏循环,当Begin = False时进入主菜单界面(左图)当按下回车后Begin = True 进入游戏(中图)左下角红色和蓝色分别为血条和能量条,可以通过能量条释放QWE三个技能,能量条共三格,右下角为分数实时统计,玩家可以通过攻击敌机和boss获得分数和能量,如果玩家死亡,Begin = False进入结算界面(右图),此时若按下ESC即会结束游戏,按下Enter进入下一次循环,回到主界面(左图),下方会显示此次游戏的最终得分。类game中有变量gamePoint 进行分数的统计(规定在不释放Q技能时打中一次+1分或者在E技能释放时也会加分)

开始/游戏/结束

背景

为实现飞机在飞的感觉,需要背景进行向下滚动,造成飞机相对向前运动。设计方案为建立背景精灵,共两张相同图片,将其中一张的x,y设置为0,0另一张放在第一张的上面,并设置其竖直方向的速度为-1,此精灵组会一起向下移动,实现背景的滚动

玩家基础

通过事件监听,判断玩家是否有按 ↑ ↓ ← → 从而实现玩家的移动,玩家最初拥有20血量,后续通

过Boss战的最高血量上限为30

玩家的技能释放和普通攻击

在类 game 中存在变量 skillPoint 进行技能点数的统计,在设计中,100点skillPoint为1技能点,1技能点可释放Q技能,2技能点可释放W技能,3技能点可释放E技能,玩家最多拥有3技能点,按下或者按住空格可进行普通攻击。攻击敌人可获得技能点,boss每掉四分之一血量也会奖励技能点0.5

Q技能:获得500发子弹,形成类似机枪的效果 不可得分 (左图)

W技能:发射一道屏障,阻挡并消灭boss子弹和敌机 不可得分 (中图)

E技能:扔出炸弹,造成巨量伤害并可得分 (右图)

Q/W/E

敌机的设计

设计在最顶端随机x位置生成敌机,并使敌机的速度通过random模组随机化,为2-6取一整数,普通敌机不可发射子弹,自身拥有两点血量。

快速编队:

每隔30s会生成快速编队事件,接受事件后,会生成一支由10个敌机组成的快速编队,每架敌机出现

位置随机,(由于太快了没有截图),通过快速冲撞对玩家构成挑战。

Boss:

两分钟会产生一个Boss。在我的设计中,Boss以及在game类中存在,但是我设计了boss类中的一个变量is_Exist用于判断是否使Boss出现在游戏中,当创建boss的事件发生后is_Exist会变为True,当boss被消灭后,is_Exist重新变为False,Boss血量为12000,意在鼓励玩家通过储存E技能打Boss,E技能可对Boss产生巨量伤害。

Boss的技能:

从图中可以看到Boss共有两种攻击技能,为发射子弹和发射屏障。子弹击中玩家玩家会丢失血量,但是玩家的子弹可以和Boss子弹相互抵消,而Boss的屏障可以阻挡玩家的子弹,并对玩家造成巨额伤害,上方红色条即为Boss的血量,可以看到,E技能对Boss造成的伤害非常高。

在设计中,发生事件boss发射子弹后,boss会在随机x位置发射四枚子弹,在发生boss发射屏障事件后,boss随机x位置发射屏障波,且为了防止玩家一直在角落就很轻松的漏洞,增大了屏障发生在左右两个角落的几率。

Boss战

游戏性设计

UI:

从上图看出共有玩家血条,玩家蓝条,boss血条,玩家分数几种UI。

玩家血条:本质为一个Surface对象,通过改变其y坐标的值而造成血条下降上升的效果,y坐标=屏幕高度-玩家血量*10,血条长度=玩家血量*10

玩家蓝条:原理同上,y坐标=屏幕高度-玩家技能点*100/2,蓝条长度=玩家技能点*100/2,为了显示蓝条值从而方便玩家观察自己的技能点数是否支持放技能,在屏幕中固定两条黑线Surface,分别指向技能点1 2的分界线和2 3的分界线

Boss血条:本质为一个Surface对象,血条长度=boss血量/30(屏幕400px宽)

玩家分数:本质为一个Surface对象,记录game类中的gamePoint的值

奖励设计:

在对战boss的途中会获得巨额分数,且boss没掉1/4的血量,会增加自己10点血量并恢复50点难度,通过E技能释放时获得巨额加分,鼓励玩家屯三格蓝条释放E技能

自定义事件设计:

为了优化设计和游戏设计从而产生了各种自定义事件:

enemy_Create = pygame.USEREVENT#制造敌机事件
player_Shot = pygame.USEREVENT + 1#储存子弹事件,主要用于子弹的有限发射优化
fast_Enemy = pygame.USEREVENT + 2#快速敌机事件
boss_Create = pygame.USEREVENT + 3#boss创建事件
boss_Shot = pygame.USEREVENT + 4#boss发射子弹事件
boss_Fire = pygame.USEREVENT + 5#boss发射屏障事件

优化设计

按键优化:为使所有的按键可以同时按且不冲突,利用pygame.key.get_pressed()获取键值,并进行

判断。此时会导致按空格时进行太快而导致子弹连发形成Q技能的效果,解决方法是创建储存子弹时间,规定时间储存子弹并限制子弹上限为2,从而使随时都能发子弹且不会产生Q技能的效果(为何不用时间发生时+空格发射子弹如:keyValue[pygame.K_SPACE] and event.type == player_Shot判断,因为这样判断会导致有时候按空格并不会发射子弹),且有效避免了发射子弹时其他按键失效的情况。

显示优化:在飞机爆炸时切换出爆炸图片,但是这样的切换只有1帧,往往观察不到,我的设计是延迟爆炸,在每一个飞机类中(敌机,玩家,boss)存在一个变量timeDelay,当检测到飞机爆炸或者受到伤害时,timeDelay开始累加,不同飞机类中timeDelay的累加最终值不同,最终值越大的延迟越大,本质上是通过一次次的循环累加timeDelay,从而时其余留的爆炸效果多加停留几帧,这样就形成了肉眼可见的图像,同样在敌机坠毁后要注意将敌机的速度降为和背景滚动速度相同,造成一种敌机已经停止运动的感觉。     

碰撞优化:由于图形Rect区域的关系,在碰撞中很多时候肉眼未相碰时已经碰撞,解决方法为减小该Rect的高度和宽度,使其小于其图像本身,从而实现精准碰撞,使子弹宽度小于玩家飞机宽度,可以避免玩家不移动只发射子弹就完全安全的局面,在完全不同的情况下,有可能被敌机或者boss子弹刮到侧面从而受到伤害。

代码设计

文件目录(fire都为屏障的意思,因为最初火焰素材没找到换为了屏障素材)

以下一个文件为一个类或者一个函数

(前缀为文件名 后缀c 类, f 函数,main.py为程序入口,main.spec为打包文件,->继承 , =》非继承)

(最基类)                boom.c, enemy.c, boss_Fire.c     

basic_Sprite.c--->background.c, boss_Bullet.c, bullet.c ===》item_Group.c->game.c===》main

                             player_Plane.c, boss.c, fire.c

game.c ===》enemyCollitionDetection.f, playerColiitionDetection.f

main===》gameMonitor.f, keyPressed.f, update.f

如图:

basic_Sprite为程序的抽象接口,为最基类,包含了其他对象的通用属性,含有图片,rect,竖直速度和水平速度的变量,具有update()函数,用以更新每帧后的对象位置

player_Plane类为玩家控制的对象boom类为玩家E技能的对象,fire类为玩家W技能的对象,bullet类为玩家普通攻击和Q技能的对象

enemy类为普通敌人对象

boss类为boss对象,boss_Bullet类为boss的子弹对象,boss_Fire类为boss的屏障技能对象

background类为背景的对象

其中player_Plane类和boss类中含有其技能和攻击的实例化精灵组,如player_Plane中含有bullet实例化对象和bullets精灵组

enemy,player_Plane,boss类中含有timeDelay变量用以延迟图像,Life变量统计血量,以及弹药及某些技能的储存判断如变量bulletStory,表示了玩家飞机的弹药储存量,isShot判断boss是否发射子弹,boss类中还含有bossExist用以判断是否存在boss,且具备attack fire boom等成员函数以发动技能和攻击

同理,boom类中也具有timeDelay对象用以延迟图像

item_Group作为一个中间传递者,含有背景,敌机,boss,玩家的实例化对象和精灵组,方便后续操作

game类具备skillPoint变量用以判断技能点的多少,gamePoint变量用以记录分数,Begin变量用以判断游戏是否发生,类中有碰撞判断成员函数,该函数调用函数enemyCollitionDetection用以检测敌机和boss是否受到攻击,playerCollitionDetection用以判断玩家是否受到伤害

main.py为程序的入口,作用为初始化pygame,设置游戏运行窗口的基本数据,设计封面和结束结算界面,进行游戏循环,初始化计时器以设置自定义事件的发生。在game.Begin为True时,即进行主游戏循环时,程序会设定帧率,gameMonitor函数用以监测事件的发生,keyPressed函数用以检测玩家键盘操作,update函数用以更新画面,形成连续图像

其中,不同的类的update方法可能与最基类不同,需要在类中重写update方法   


海纳百川 有容乃大