当前位置: 首页 > 科技观察

500行代码,教你用Python写一个微信飞机大战

时间:2023-03-21 01:38:46 科技观察

这几天在微信小游戏里重温飞机大战,边玩边思考人生,这个飞机大战怎么能做得这么好,操作简单,使用方便。帮蹲便器、YP、饭圈妹子无聊的时候找点乐子提神!让他们的左手/右手有节奏有节奏地朝同一个方向前后移动!这是史诗般的发明,是强势的一击,是……一阵抽搐后,我结束了游戏,瞬间觉得一切都无趣了。进入贤者模式的时候突然想到,如果能让更多的人换一种方式去体验,看到这样美好的感觉是不是很美好呢?于是打开电脑,新建了一个plan_game.py...先看渲染效果运行环境操作系统:windows10python版本:python3.7代码编辑器:pycharm2018.2使用的模块:os,sys,random,pygame使用第三个-pygame的第三方模块,因为实现代码使用了pygame的第三方模块。-novice-professional-index/具体实现首先我们先指定素材文件的文件目录,方便我们后面的使用。importos#获取当前文件夹下material_images目录的路径source_dir=os.path.join(os.path.dirname(os.path.abspath(__file__)),'material_images')实现一个Game类完成游戏main逻辑。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'''self.size=sizeself.screen=pygame.display.set_mode(size)self.title=titleself.background_image_path=background_image_pathself.background=pygame.image.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#2seconds#fractionself.score=0#存储所有敌机self.enemies=[]defshow_score(self):'''显示得分,窗口顶部距离topmargin10px,左右居中'''passdefset_time_passed(self):#控制画的边框,越大越好thefaster#获取上次绘制图像到现在的时间,msself.time_passed=self.clock.tick()defdraw_background(self):'''绘制背景图向下滚动营造飞机飞行的感觉一直向上'''#每次移动距离=每米s移动距离*上次到现在的时间(ms)passdefcreate_enemy(self,image_path=os.path.join(source_dir,'enemy1.png'),enemy_number=5):'''创建敌机:paramimage_path:enemy机器图片地址:paramenemy_number:屏幕上最多有几架敌机'''passdefdraw_enemies(self,time_passed,screen):'''将敌机画到屏幕上,清理掉跑出的敌机window,:paramtime_passed:up当前第二个绘图引导经过的时间:paramscreen:绘制的窗口对象'''passdefbullet_and_enemy_crash_detection(self,bullets):'''检测子弹是否击中敌机:parambullets:所有的子弹theplane'''passdefplan_and_enemy_crash_detection(self,plan,allow_crash_size=None):'''检测敌机是否与飞机碰撞:paramplan:aircraftobject:paramallow_crash_size:允许飞机碰撞的大小,只有left和right有效'''passdefdraw_plan(self,plan,time_passed):'''绘制plane:paramplan:Aircraftobject:paramtime_passed:timesincelastdrawing:return:'''passdefgame_over(self):'''gameover'''whileTrue:#Drawbackgroundimagepassdefrun(self):'''游戏入口函数,startfunction,mainfunction:return:'''#设置游戏窗口的大小pygame.display.set_caption(self.title)#初始化一个飞行器对象plan=Plan()whileTrue:#如果飞行器自毁,则游戏结束,调用game_over函数pass#检测监听事件pass#检测上下左右移动情况。#w,a,s,d和上下左右键都可用#然后执行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)#Drawbulletsplan.draw_bullets(time_passed=self.time_passed,screen=self.screen)#Displayourimagepygame.display.update()这是检查你的字体的方法system.pygame.font.get_fonts(),该函数可以获取系统中所有内置的字体文件。但是,当我们的游戏有中文的时候,我们也必须选择支持中文的字体,否则不会显示中文。实现DestroyAnimationMixin类,主要用于显示飞机或敌机自毁动画():defshow_destroy_animation(self,time_passed,destroy_time=200):'''显示自毁动画这个动画其实就是几张图片快速切换,我们的眼睛是看不出来的,所以我们认为是动态的,也就是,动画: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。加载(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,方便使用显示自毁动画的功能':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=[]#destroyassociationattributes,自毁相关属性#StartselfDestroyself.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,方便使用显示自毁动画的功能)):''':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=['enemy1_down1.png','enemy1_down2.png','enemy1_down3.png','enemy1_down3.png']#自毁时间上次绘制图像的时间self.time_passed=0#自毁图像在self.destroy_images中的位置self.destroy_image_position=0defupdate(self,time_passed):'''更新positio敌机的n:paramtime_passed:自上次绘制图像的时间:return:'''pass实现了bullet类,完成了bullet的主要操作#AirplanebulletclassclassBullet():def__init__(self,image_path=操作系统。path.join(source_dir,'bullet.png'),background_size=(480,700),plan=None,speed=1000):''':paramimage_path:子弹图像地址:parambackground_size:游戏窗口大小:paramplan:飞行器对象: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):'''根据plan获取子弹位置:paramplan:aircraftobject'''bullet_size=self.image.get_size()plan_width=plan.image_size[0]x=(plan_width-bullet_size[0])/2return[plan.position[0]+x,plan.position[1]]defupdate(self,time_passed):'''改变子弹的位置:paramtime_passed:从上次绘制图像到present'''#如果子弹超出屏幕或者击中敌机,设置self.position[1]为-100,plan.draw时去掉ifself.position[1]+self.image.get_size()[1]<=0orself.destroyed:self.position[1]=-100return#Changeddistance=time*speedself.position[1]-=time_passed*self.speed这样,我们就完成了所有的操作,接下来我们只需要使用Game().run(),我们就可以运行我们的游戏