《基于python的飞机大战游戏设计.docx》由会员分享,可在线阅读,更多相关《基于python的飞机大战游戏设计.docx(11页珍藏版)》请在课桌文档上搜索。
1、基于python的飞机大战游戏设计摘要:基于Python软件的面向对象编程思想设计飞机大战游戏,玩家操作飞机发射子弹,通过左右移动来躲避子弹;敌机位于屏幕顶部左右匀速移动,并且随机向玩家飞机发射子弹。实践表明,该游戏操作简单灵活,具有趣味性。关键字:Pyrthon;飞机大战游戏;PygameDesignofAircraftWarGameBasedonPythonAbsrtact:Basedontheobject-orientedprogrammingideaofPythonsoftware,theaircraftwargameisdesigned.Playersoperatetheaircra
2、fttofirebullets,andavoidbulletsbymovingleftandright;theenemyaircraftislocatedatthetopofthescreen,movingleftandrightataconstantspeed,andrandomlyfirebulletsattheplayer,saircraft.Practiceshowsthatthegameissimple,flexibleandinteresting.Keywords:Pyron;airplanewargame;pyGame目录一、飞机大战游戏总体设计2(一)总体设计原则1(二)系统总
3、体设计2(三)准备工作2二、飞机大战游戏功能实现3(-)显示玩家飞机3(二)玩家飞机发射子弹3(三)敌人飞机3三、优化程序代码4(-)抽取子弹基类(二)抽取飞机基类4结语20参考文献22PythOn是一种开源的简单易学的高级语言,应用场景涉及到Web应用开发、操作系统管理、科学计算、游戏等领域。飞机大战是一款飞行射击类游戏,游戏方法是玩家操作飞机与敌机在空中战斗。本文主要介绍用Python软件实现飞机大战游戏。游戏的整个界面是一张背景图片,游戏中用到的其他角色同样都对应着相应的图片,这些图片需要借助Pygame模块搭载窗口以显示J。在窗口中,对象显示的位置通过坐标标注。其中,窗口的左上角坐标为
4、(0,0),石轴向右延伸坐标数值增大,y轴向下延伸坐标数值增大。所有的游戏元素都参考这个坐标系,对象在窗口的移动就是坐标位置的变化。1飞机大战游戏总体设计Ll总体设计原则主要设计原则如下:(1)简单性。在实现软件的功能的同时,尽量让软件操作简单易懂;(2)针对性。基于Python软件,实现飞机大战游戏的各种要求;(3)一致性。类型、变量和其他元素的命名规则保持一致;完成同样的功能应该尽量使用同样的元素;界面元素的外观风格、摆放位置在同一个界面和不同界面之间是一致的。1.2系统总体设计系统中只有玩家一种用户,不必进行身份验证等操作。玩家点击应用图标直接进入开始界面。整个游戏的操作包括:显示玩家飞
5、机、控制移动方向;显示玩家发射子弹(子弹移动);显示敌人飞机,控制敌人飞机移动、敌人飞机发射子弹。1.3准备工作1.3.1添加pygame模块pygame是一套用来开发游戏的Python模块,该模块允许在Python程序中创建功能丰富的游戏和多媒体程序。Pycha珊作为一款开发Python的编辑器,它不仅可以帮助开发人员提高开发效率,而且包含了像pygame这样功能丰富的第三方模块。在PyCharm中添加pygame模块,在程序中导人pygame模块进行测试,编译器编译通过,就证明成功导入了模块。1. 3.2搭建游戏界面飞机大战游戏的整个场景都需要一个窗口作为载体,展示游戏中的画面。为了让整个
6、游戏的角色和背景的风格统一,准备了一张背景图片。在开发中,导入Pyg砌e模块,就能直接调用模块中的方法。1. 3.3检查键盘的输入当敌人飞机发射子弹的时候,玩家飞机需要使用键盘适时地调整位置,以躲避子弹的攻击。在PythOn程序中,移动鼠标、敲击键盘等人机交互的动作属于事件,它交由pygame的event模块进行控制。event模块采用列表形式存储的事件,可以通过get函数来获取。如果要获取键盘和鼠标产生的事件,就使用for循环遍历事件列表,取出每个事件与event.type(事件的类型)进行对比。如果event.type的值为QUit,说明用户使用鼠标点击了窗口右上角的关闭按钮,此时就要退出
7、程序;如果event.type的值为KeydOWn,说明用户使用了键盘,此时就要明确按下的是哪个键。在While循环中,已经显示了游戏的背景图片。这时,在程序中需要检测是否有事件发生,比如按下键盘等。如果没有事件发生,就执行更新操作,如果有事件发生,就先处理键盘事件以后再更新。2飞机大战游戏功能实现2. 1显示玩家飞机,控制移动方向在窗口中要显示玩家飞机,可以根据玩家飞机图片的名称创建图像,再把这些图像显示到屏幕上设定的位置。玩家飞机左右移动功能,可以通过改变坐标戈的值实现,飞机向左移动减小坐标石的值,反之则增大戈的值。新建一个PythonFi1e,取名为planew.在Plane.Py文件中
8、,导入Pygalne模块,之后定义一个表示玩家飞机的类HeroPIane。程序设计中,定义为display、move一1eft和move一right三种方法。其中,display用于在默认的位置显示玩家飞机;moveleft用于让飞机向左移动;moveri曲t用于让飞机向右移动。在Stan函数中创建飞机对象,并且显示到窗口中。在Whiletme语句中,根据玩家按下的按键来调用相应的方法,以控制飞机移动的方向。当按“卜”键或者“A”键时,控制玩家的飞机向左移动,当按“_+”或者DI,键时,控制玩家的飞机向右移动。野飞机大战-X2.2玩家飞机发射子弹2.2.1显示子弹当按空格键时,代表玩家飞机要发
9、射一枚子弹,此时需要在玩家飞机的头部位置生成一颗子弹对象。飞机左右移动到任意位置,只要按空格键,子弹生成的初始位置永远会位于玩家飞机的头部。新建一个PythOnFile,取名“bullet“。在bul-let.Py文件中,导人模块,之后定义一个表示子弹的类。代码如下:classBul1et(object):definit一(seif,x,y,Screen):seII.x=x+40semy=y-20seII.screen=screensemi砌ge=pygame.image.IOad(./feij/bulkt一3.班”).convert()def.display(seif):semscreen,
10、blit(seif.iamge,(semx,seif.y)按空格键发射子弹,代码如下:hemPlalle.Iauncn-bullet()运行程序,按下空格键以后,玩家飞机的头部显示了待发射的子弹。此时,无论飞机移动到哪个位置,生成的新的子弹永远会位于其顶部。&-mfi-XIScorer313%52. 2.2子弹移动每执行一次Whi1e循环,就会调用一次dis-play方法,让子弹再次显示到屏幕上。由于屏幕刷新的速度特别快,肉眼是无法捕捉到的。利用程序的这个特点,每刷新一次屏幕,就让子弹显示的位置上移几个单位,从而形成向上发射子弹的动画效果。如果无限制地往列表中添加子弹对象,终究会耗尽设备的内存
11、,所以,一旦子弹离开屏幕可视范围时;就把子弹对象从列表中删除。在BUIICt类中添加一个judge方法,用于反馈子弹是否发射到屏幕以外的情况,若子弹图像的y值小于0,则表示子弹移出了屏幕,返回Tme;反之则返回False.在HeroPlane类的display方法中,定义一个存放待删除子弹对象的列表。从列表中取出每个带删除的子弹对象进行判断,如果子弹对象已经发射到屏幕的外面,就添加到刚定义的列表中,然后清空列表中所有被删除的子弹对象。具体代码如下:defdisplay(seif):seif.screen,blit(semimage,(semx,seif.y)neen一del-Iist-fori
12、teminse噱bul1吼一1ist:i“tem.judge():need一del一1ist.append(item)fjfdel一iteminneed一del一1ist:seif.bull吼一1ist.remove(del一item)forbuIIetinsembuIIel一1ist:bul1et.display()bul1et.move()2. 3敌人飞机2. 3.1显示敌人飞机跟玩家飞机类似,在plane.py文件中定义一个表示敌人飞机的EnemyPIarle类。敌人飞机应该有默认的位置、呈现图像的窗口、存放子弹的列表这些属性。然后来到main函数的While循环语句中,在创建HerOP
13、lane类对象的后面,创建表示敌人飞机的对象。在显示玩家飞机的代码后面,调用display方法来显示敌人飞机。留飞机大战-X2.3.2控制敌人飞机移动当程序启动以后,敌人的飞机开始在窗口的顶部做直线运动,直到碰到屏幕的边缘后向反方向做直线运行。可以为敌人飞机类添加一个移动的方法,由于敌人的飞机是不停地运动的,所以放到While语句中最为合适口J。飞机碰到左侧的屏幕边缘时,移动方向变化为向右移动,飞机碰到右侧的屏幕边缘时,移动方向变为向左移动。因此,在EnemyPlane类的一im()方法中增加一个direction属性,用于记录飞机的初始运动方向:sell.direction=d曲t”然后定义
14、一个move方法,根据飞机移动的方向改变石对应的坐标值,再根据菇的值限定敌人飞机移动的范围,只要超过屏幕的宽度范围,就改变飞机运动的方向。在Inain.py文件的Whi1e语句中,调用display()方法显示敌人飞机,调用move方法实现敌人飞机一直左右移动的效果。运行程序,敌人飞机在屏幕顶部移动的速度非常快。产生这种情况,主要因为屏幕刷新的速度太快,导致敌人飞机移动的速率过快,并且占用了程序过多的内存,因此,需要使用time模块来降低程序执行的效率。2. 3.3敌人飞机发射子弹敌人飞机发射子弹的功能与玩家飞机发射子弹的功能基本一样,不同的是子弹反射的方向及发射的个数。为此,在bullet.
15、Py文件中,新建一个表示敌人飞机发射的子弹的EnemyBul1et类,直接复制Bul1et类的代码到EnemyBul1et类中,然后再对发射子弹的功能代码进行局部调整。在Inain.Py文件的循环语句中,调用move方法的后,调用敌人发射子弹的方法为:Enemy一plane.Iauncn-buuet()运行程序,由于敌人飞机发射子弹的速度太快了,使得子弹形成了一条斜线。所以,在Enen.myPlane类的1auncn一bul1et(发射子弹)方法中,设置发射子弹的数量是随机的,这样可以降低子弹发射的频率,代码如下:def1auncn_buUet(8elf):nulnber=random.ran
16、dint(1,100)ifUlIIlber=88:new一bul1et=Ene皿甲BUl1et(seif.x,seif.y,seif.scleenlseif.bul1et一Iist.印Pend(new-bul1et)上述方法实现了敌人飞机发射子弹的功能,首先使用函数获取了从1到100的随机整数,然后使用if语句判断随机数的值是否与88相等,只有这两个值相等,才会创建要发射的子弹对象,通过这种随机数的方式,使得敌人发射子弹的数量变为原来的百分之一。由于使用了random模块的函数,所以导入random模块3|,代码为:Importrandom3优化程序代码在前面的程序代码中,表示敌人飞机的类(E
17、nemyPlane)和表示玩家飞机的类(HeroPlane)中有很多功能相似的代码,除此之外,表示子弹的两个类中有着很多重复的代码,这些重复的代码不仅使程序显得过于臃肿,而且没有清晰的结构。可以利用继承的技巧H,对所有类的代码进行优化,以明确程序的结构。3. 1抽取子弹基类玩家飞机发射的子弹和敌人飞机发射的子弹这两大类的功能几乎相同,出现了很多重复的代码,使得整个程序的结构过于臃肿。可以定义这两个类的公共类PublicBul1et.J,在这个类中既能抽取出它们共同拥有的功能,又能区分它们的不同情况。定义一个表示子弹的公共类PUblicBul1et,把示玩家飞机子弹类的代码复制到PUblicBu
18、l1et类中,再根据两个子弹类不同的地方进行调整。由于PUbIicBul1et类已经合并了EnemyBul1et类和Bul1et类的功能,并对它们各自不用的地方进行了处理,所以创建EnemyBUIIet类和BUlIet类对象时,可以替换为创建PUblicBul1et类对象:New-buIIet-PublicBuUet(seif.x,seif.y,seif.screen,enemy,)同样在HerOPIane类的1auncn一bul1et方法中,把创建BUl1et类对象的代码改为创建Pub-1 icBul1et类的对象:New-bullet=PUblicBul1et(seif.x,semy,se
19、ll.screen,“hero)运行程序,界面依然显示了跟以前一样的效果,这证明代码抽取成功。EnemyBul1et类和BUl1et类现在对程序没有起任何作用,可以直接删除。3. 2抽取飞机基类进一步抽取EnemyPlane和HeroPlane两个类中功能相似的代码。由于这两个类中实现的功能较多,如果依然使用抽取公共类的技巧,就需要频繁地使用if一elSe语句来区分不同飞机的情况。因此,需要把EnenIyPlane和HerOPIane类中相同的功能放到基类中,再让这两个类继承基类后单独调整。通过比较EnemyPlane和HerOPlanc类中的代码,发现EnenIyPlane类中的一im一、d
20、isplay和She一Bul1et方法与HerOPlane类中的一im一、display和SheBUl1et方法功能非常相似。为此,需要把这三个方法的代码提取到基类中,子类EnemyPlane和HeroPlane继承基类以后,会拥有这三个方法,可以根据自己的要求重写这些方法。3. 2一init-()方法通过比较两个飞机类的代码发现,Enemy一Plane类的一in”一()方法比HeroPlane类的一in一()方法中多一个属性,所以需要把HerOPlane类的一in“一()方法粘贴到新创建的基类Plane中,具体如下:ClassPlalle(object):def一init一(seif,scr
21、een):seif.x=230semy=600seif.scleen=scleenseif.image一n棚e=./feijhem.gif,seif.image-pygame.image.10ad(seHimage一name).convert()seMbul1吼一Iist=让HeroPlane类继承Plane类,这样HeroPlane类就拥有了从父类Plane继承来的一im()方法。此时,可以删除类HeroPlane中一im()方法。同样让EnemyPlane类继承自Plane类,Plane类就拥有了从父类继承而来的一im一()方法。不过,EneOiyPlane类需要增加一个表示方向的属性,为
22、此需要重写父类的一int一()方法,具体如下:def一init一(seif,screen):super().一ini一(screen)self,direction=right,3. 2.2display方法通过比较EneInyPIane类和HerOPlane类的display方法发现,它们的功能是一样的。因此,可以在Plane类中沿用EnemyPlane类的display方法代码。由于EnemyPlane类和HemPlane类都已经继承了Plane类,所以就拥有了display方法,而且它们的功能没有任何变化,直接删除它们每个类中的display方法就行了8葭3. 2.31 aunch-bul
23、1et方法为了能区分是哪架飞机要发射子弹,在创建飞机对象构造方法的参数列表中,增加一个表示飞机名称的字符串。虽然这样能区分飞机的名称,但是方法参数中直接使用字符串扩展性不是很好。因此,在Plane类的一in”一方法中,添加表示飞机名称的name属性,使得EnemyPlane类和HemPlane类创建对象时就有了名字。在EnemyPIane类重写的方法中,增加name参数。在类的方法中,把创建PublicBul1et类对象的参数列表中的最后一个参数改为seif.nameO改完以后,把整个1auncn-bul1et方法剪切到PIane类中。代码如下:defIaunc-bul1et(seif):ne
24、wbul1et=PublicBul1et(seif.x,seif.y,seif.8creen,seif.namesseif.bul1e一1ist.印pend(new-bul1et)EnemyPlane类中的1auncn一bul1et方法,与从父类直接继承的1auncn一bul1et方法在功能上存在着一些差异。为此,EnenlyPlane类需要重写从父类继承的1auncn一bul1et方法。在PIane类的一im()方法中,由于图片素材的名称、戈值和y值是变化的,每个子类需要单独进行调整,所以在Plane类中,把这三个属性移动到子类HeroPIane重写的一im()方法中。在EnefnyPlan
25、e类的一im()方法中,同样增加这三个属性的设置。这表示抽取成功。此时,程序中几个类的结构,4结论本文围绕面向对象的编程思想,开发了飞机大战游戏的部分功能,包括搭建游戏界面,创建玩家飞机和敌人飞机类,飞机发射子弹等,并且利用继承的技巧优化了代码。模块以对象划分,有界面模块、Her。模块、子弹模块、Enemy模块、游戏控制模块;难点在于多架战机同时出动情况下,判断发生碰撞的算法设计。整个软件按照预期目标大致实现了飞机大战游戏的功能。整个游戏还存在一些不足。比如,怎么动态及时地显示积分数,怎么能够让各种敌机在不同的时间点以不同速度飞行且不发生碰撞;还有如何在多人联网下共同作战,及时分享自己的战绩等,都需要进一步研究。参考文献:1吴矶震.飞机大战游戏软件中的数据结构和策略分析J.信息与电脑,2016(7):145-154.2杨大生.基于SyInbian平台飞机大战游戏设计J.福建电脑,2010(7):140167.3李智鹏.基于Unity3D引擎的空中战机游戏设计与实现D.长春:吉林大学,2016.4黑马程序员.Python快速编程入门M.北京:人民邮电出版社,2018.5雷丽娟,郑永彬.使用Java制作贪吃蛇游戏J.科技视界,2013(4):139140.6仇宾.基于Java的“连连看游戏J.电脑编程技巧与维护,2013(11):7277.
链接地址:https://www.desk33.com/p-90230.html