这几天在微信小游戏里重温飞机大战,边玩边思考人生,这个飞机大战怎么能做得很好,操作简单,易于使用。帮蹲厕达人、YP达人、饭圈妹子无聊的时候找点乐子提神!让他们的左手/右手有节奏有节奏地朝同一个方向前后移动!这是史诗般的发明,是一笔彩笔,是……一阵抽搐后,我结束了游戏,瞬间觉得一切都无聊透了。当我进入贤者模式的时候,我突然想到,如果我能做出更多的人以不同的方式体验这种美好的感觉,岂不是很美妙?于是打开电脑,创建了一个plan_game.py...先看渲染效果运行环境操作系统:windows10Python版本:python3.7代码编辑器:pycharm2018.2使用的模块:os,sys,random,pygame因为实现代码使用apygame如果没有第三方模块,请先pip安装。顺便说一句,这里有一个更好的pygame教程。https://eyehere.net/2011/python-pygame-novice-professional-index/具体实现,我们先指定material文件的文件目录。方便我们以后的使用。这些素材已经全部上传到公众号Python专栏,后台回复:飞机大战,你可以拿到。importos#获取当前文件夹下material_images目录的路径source_dir=os.path.join(os.path.dirname(os.path.abspath(__file__)),'material_images')实现一个Game类来完成这个游戏的主要逻辑。importpygameclassGame():def__init__(self,background_image_path,size=(480,700),title='飞机大战',font_name='方正书体',font_size=30,speed=2000):''':parambackground_image_path:背景图片路径地址:paramsize:游戏窗口大小:paramtitle:游戏窗口标题:paramfont_name:指定字体:paramfont_size:指定字体大小:paramspeed:播放时间背景图像滚动整个窗口一次,单位为ms'''load(self.background_image_path).convert()#设置字体对象获取系统自带的字体self.font=pygame.font.SysFont(font_name,font_size)#获取Clock对象,我们可以用它来获取从上次绘制图像开始的时间self.clock=pygame.time.Clock()#背景图片的初始位置self.height=0#使用窗口的高度来滚动,可以得到每ms的滚动距离self.every_ms_move_distance=self.size[1]/speed#2秒#给自己打分。分数=0#存储所有敌机self.enemies=[]defshow_score(self):'''显示得分,在窗口顶部,外边距10px,左右居中'''passdefset_time_passed(self):#控制绘图的帧,越大越快#获取图像从上次绘制到现在的时间,msself.time_passed=self.clock.tick()defdraw_background(self):'''画背景图,一直往下滚动,营造出飞机一直飞起来的感觉'''#每次移动的距离=每毫秒移动的距离*上次到现在的时间(ms)passdefcreate_enemy(self,image_path=os.path.join(source_dir,'enemy1.png'),enemy_number=5):'''createenemy:paramimage_path:敌人的图像地址:paramenemy_number:敌人的最大数量screen'''passdefdraw_enemies(self,time_passed,screen):'''在屏幕上绘制敌机,并清理跑出窗口的敌机,:paramtime_passed:自上次引导绘制以来经过的时间:paramscreen:绘制的窗口对象'''passdefbullet_and_enemy_crash_detection(self,bullets):'''检查子弹是否击中敌机:parambullets:飞机的所有子弹'''passdefplan_and_enemy_crash_detection(self,plan,allow_crash_size=None):'''检测敌机是否与飞机碰撞:paramplan:planeobject:paramallow_crash_size:飞机碰撞允许的大小,只有左右有效'''passdefdraw_plan(self,plan,time_passed):'''绘制平面:paramplan:planeobject:paramtime_passed:自上次绘制以来的时间:return:'''passdefgame_over(self):'''游戏结束'''whileTrue:#绘制背景图passdefrun(self):'''游戏入口函数,开始函数,主函数:return:'''#设置游戏窗口大小pygame.display.set_caption(self.title)#初始化一个飞行器对象plan=Plan()whileTrue:#如果飞行器自毁完成,游戏结束,调用game_over函数pass#检测监听事件pass#检测up的运动情况、下、左、右。#w,a,s,dandup,down,left,可以右键#然后执行plan.update函数改变飞机pass的位置#子弹与敌机的碰撞检测self.bullet_and_enemy_crash_detection(plan.bullets)#飞机与敌机的碰撞检测self.plan_and_enemy_crash_detection(plan)#设置属性time_passed的值,从上次算起的时间,方便后面使用self.set_time_passed()#绘制背景图片self.draw_background()#显示分数self.show_score()#生成敌机self.create_enemy()#绘制敌机self.draw_enemies(time_passed=self.time_passed,screen=self.screen)#绘制飞机self.draw_plan(plan=plan,time_passed=self.time_passed)#绘制子弹plan.draw_bullets(time_passed=self.time_passed,screen=self.screen)#显示我们的图像pygame.display.update()这里是检查你有哪些字体的方法在你的system.pygame.font.get_fonts()中,这个函数可以获取系统中所有的内置字体文件。但是,当我们的游戏有中文的时候,我们也必须选择支持中文的字体,否则不会显示中文。实现DestroyAnimationMixin类,该类主要用于显示飞机或敌机的自毁动画#显示飞机自毁动画的Mixin类,可用于飞机和敌机的自毁动画显示classDestroyAnimationMixin():defshow_destroy_animation(self,time_passed,destroy_time=200):'''显示自毁动画动画其实就是几张图片切换的比较快,我们的眼睛无法识别,所以我们认为是动态的,即is,animation:paramtime_passed:从上一次绘制图像到现在的时间,单位为ms:paramdestroy_time:自毁动画的总显示时间,单位为ms'''#因为我们有四个自毁破坏图像,它们需要按顺序显示。一、动画的效果#self.destroy_image_position表示第几章自毁图片,从0开始#如果大于等于4,则表示自毁动画显示完成,设置self.destroyed变量为True,这样方便在别处调用ifself.destroy_image_position>=4:self.destroyed=Truereturn#顺序加载自毁图像ifself.time_passed>=destroy_time/4:self.image=pygame.image.load(os.path.join(source_dir,self.destroy_images[self.destroy_image_position])).convert_alpha()self.destroy_image_position+=1self.time_passed=0else:self.time_passed+=time_passed实现飞机类和完成飞行器的主要操作。飞行器的操作包括:飞行器的位置、飞行器的子弹、子弹的发射。#Airplane类,继承了DestroyAnimationMixin,方便使用显示自毁动画类的功能Plan(DestroyAnimationMixin):def__init__(self,image_path=os.path.join(source_dir,'plan.png'),background_size=(480,700)):''':paramimage_path:飞机图像地址:parambackground_size:游戏窗口大小'''self.background_size=background_sizeself.image=pygame.image.load(image_path).convert_alpha()self.image_size=self.image.get_size()self.position=[(background_size[0]-self.image_size[0])/2,500]#飞机每次移动的距离self.every_time_move_distance=0.5#飞机的子弹self.bullets=[]#销毁关联属性,自毁相关属性#开始自毁self.start_destroy=False#自毁结束self.destroyed=False#自毁图像self.destroy_images=['me_destroy_1.png','me_destroy_2.png','me_destroy_3.png','me_destroy_4.png']#自毁图像位置self.destroy_image_position=0#从上次绘制图像到现在自己的时间.time_passed=0defupdate(self,direction):'''更新飞机的位置:paramdirection:飞机的方向'''passdefshut(self,image_path=os.path.join(source_dir,'bullet.png')):'''飞机发射子弹:paramimage_path:子弹图片'''passdefdraw_bullets(self,time_passed,screen):'''绘制飞机的所有子弹:paramtime_passed:时间从上次画图到现在:paramscreen:在哪个窗口画'''pass实现敌机类别,完成敌机的主要操作主要是更新位置。#Enemy类,继承DestroyAnimationMixin,方便使用显示自毁动画的功能classEnemy(DestroyAnimationMixin):def__init__(self,image_path=os.path.join(source_dir,'enemy1.png'),speed=2000,background_size=(480,700)):''':paramimage_path:敌机图片地址:paramspeed:敌机移动整个窗口所花费的时间,单位ms,即速度:parambackground_size:游戏窗口大小'''self.image=pygame.image.load(image_path).convert_alpha()self.speed=background_size[1]/speedself.background_size=background_sizeself.position=[random.randint(0,background_size[0]-self.image.get_size()[0]),-self.image.get_size()[1]]#开始自毁self.start_destroy=False#自毁完成self.destroyed=False#自毁图片路径self.destroy_images=['敌人1_down1。png','enemy1_down2.png','enemy1_down3.png','enemy1_down3.png']#自上次绘制图像以来的时间self.time_passed=0#Self.destroy_imagespositionself.destroy_image_position=0defupdate(self,time_passed):'''更新敌机位置:paramtime_passed:从上次绘制图像到现在的时间:return:'''pass实现子弹类,完成主要操作子弹的#AirplanebulletclassBullet():def__init__(self,image_path=os.path.join(source_dir,'bullet.png'),background_size=(480,700),plan=None,speed=1000):''':paramimage_path:bulletImageaddress:parambackground_size:Gamewindowsize:paramplan:Aircraftobject:paramspeed:子弹飞行速度'''self.image=pygame.image.load(image_path).convert_alpha()self.background_size=background_sizeself.speed=background_size[1]/speed#子弹是否击中敌机self.destroyed=Falseself.position=self._get_position(plan)def_get_position(self,plan):'''获取子弹根据计划的位置:paramplan:Planeobject'''bullet_size=self.image.get_size()plan_width=plan.image_size[0]x=(plan_width-bullet_size[0])/2return[plan.位置[0]+x,plan.position[1]]defupdate(self,time_passed):'''改变子弹的位置:paramtime_passed:自上次绘制图像以来的时间'''#如果子弹超出屏幕或击中敌机,只需将self.position[1]设置为-100,并在plan.drawifself.position[1]+self.image.get_size()[1]<=0或self.destroyed时将其移除:自己。position[1]=-100return#改变了distance=time*speedself.position[1]-=time_passed*self.speed这样我们就完成了所有的操作,接下来只需要使用Game()即可。run(),就可以运行我们的游戏了关注公众号:Python专栏,后台回复:AirplaneWars,可以获得完整的代码和素材包。
