使用python制作一个飞机大战游戏
使用python制作一个飞机大战游戏?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
具体内容如下
importgc importrandom importpygame #玩家飞机精灵类 importConstants classHeroPlane(pygame.sprite.Sprite): def__init__(self,screen): #调用父类初始化方法 #pygame.sprite.Sprite.__init__(self) super().__init__() #窗口 self.screen=screen #一个玩家飞机图片 self.image=pygame.image.load('./feiji/feiji.png') #飞机矩形区域对象 self.rect=self.image.get_rect() #左上角坐标 self.rect.topleft=[512/2-116/2,600] #飞机的速度 self.speed=15 #一个精灵组存放所有的子弹精灵 self.bullets=pygame.sprite.Group() #血量初始100 self.blood_value=100 #标记玩家飞机是否over self.is_remove=False #显示爆炸图片的索引从0开始 self.mIndex=0 #存放爆炸图片的列表 self.bomb_mImages=[] forvinrange(1,15): #把所有图片存到列表里每个图片存2次 self.bomb_mImages.append(pygame.image.load('./feiji/image'+str(v)+'.png')) self.bomb_mImages.append(pygame.image.load('./feiji/image'+str(v)+'.png')) defkill_blood(self,kill_value=10): """血量减少""" self.blood_value-=kill_value print('被打中了,血量还剩%s'%self.blood_value) ifself.blood_value<=0: #避免血量负值 self.blood_value=0 #血量<=0设置is_remove为True self.is_remove=True defkey_control(self): """按键监听操作飞机上下左右和发子弹""" #监听键盘事件 key_pressed=pygame.key.get_pressed()#注意这种方式是能够检测到一直按下不松开的键盘 ifkey_pressed[pygame.K_w]orkey_pressed[pygame.K_UP]: #top值如果小于0就到了最顶部不要再移动了 ifself.rect.top>3: self.rect.top-=self.speed ifkey_pressed[pygame.K_s]orkey_pressed[pygame.K_DOWN]: ifself.rect.bottom<=768: self.rect.bottom+=self.speed ifkey_pressed[pygame.K_a]orkey_pressed[pygame.K_LEFT]: ifself.rect.left>0: self.rect.left-=self.speed ifkey_pressed[pygame.K_d]orkey_pressed[pygame.K_RIGHT]: ifself.rect.right<520: self.rect.right+=self.speed ifkey_pressed[pygame.K_SPACE]: #print("space") #创建3个子弹 bullet1=Bullet(self.screen,self.rect.left,self.rect.top,1) bullet2=Bullet(self.screen,self.rect.left,self.rect.top,2) bullet3=Bullet(self.screen,self.rect.left,self.rect.top,3) #添加到精灵组 self.bullets.add(bullet1,bullet2,bullet3) defbomb(self): print('玩家飞机爆炸中') """显示爆炸图片""" self.screen.blit(self.bomb_mImages[self.mIndex],self.rect) self.mIndex+=1 print('mIndex',self.mIndex) ifself.mIndex>=len(self.bomb_mImages): #播放到了最后爆炸结束返回True returnTrue defupdate(self): ifself.is_remove: print('玩家飞机挂掉') #如果玩家飞机挂掉 ifself.bomb(): #爆炸结束 print('爆炸结束') self.rect.topleft=[-200,-200] #开启倒计时 pygame.time.set_timer(Constants.game_over_id,1000) #把玩家飞机指向None停止update manager.hero=None else: self.key_control() self.display() defdisplay(self): #ifself.blood_value<=0: ##如果血量小于0移出窗口 #self.rect.topleft=[-200,-200] #把飞机显示到窗口上飞机116*100 self.screen.blit(self.image,self.rect) #更新精灵组里的子弹位置 self.bullets.update() #精灵组所有子弹显示到窗口 self.bullets.draw(self.screen) classBullet(pygame.sprite.Sprite): #path_num表示散弹中子弹是哪一个 def__init__(self,screen,planex,planey,path_num): #调用父类初始化方法 #pygame.sprite.Sprite.__init__(self) super().__init__() #窗口 self.screen=screen #一个子弹图片 self.image=pygame.image.load('./feiji/bullet_12.png') #子弹矩形区域对象 self.rect=self.image.get_rect() #子弹左上角坐标 self.rect.topleft=[planex+48,planey-20] #子弹的速度 self.speed=15 #path_num表示散弹中子弹是哪一个 self.path_num=path_num defupdate(self): """修改子弹坐标""" self.rect.top-=self.speed ifself.rect.bottom<0: #子弹已经移出了屏幕上方这时把子弹从精灵组删除 self.kill() ifself.path_num==1: pass elifself.path_num==2: #如果等于2就是左侧的散弹 self.rect.left-=10 elifself.path_num==3: #如果等于3就是右侧的散弹 self.rect.right+=10 #敌机精灵类 classEnemyPlane(pygame.sprite.Sprite): #创建类属性存放所有飞机的所有的子弹 all_bullets=pygame.sprite.Group() def__init__(self,screen): #调用父类初始化方法 #pygame.sprite.Sprite.__init__(self) super().__init__() #窗口 self.screen=screen #一个玩家飞机图片 self.image=pygame.image.load('./feiji/img-plane_5.png') #飞机矩形区域对象 self.rect=self.image.get_rect() #左上角坐标x坐标随机 self.rect.topleft=[random.randint(0,412),0] #飞机的速度 self.speed=3 #一个精灵组存放所有的子弹精灵 self.bullets=pygame.sprite.Group() #敌机的左右方向默认一开始向右 self.direction='right' #子弹的精灵组 self.bullets=pygame.sprite.Group() #标记敌机是否被击中是否要删除 self.is_remove=False #显示爆炸图片的索引从0开始 self.mIndex=0 #存放爆炸图片的列表 self.bomb_mImages=[] forvinrange(1,14): #把所有图片存到列表里每个图片存2次 self.bomb_mImages.append(pygame.image.load('./feiji/image'+str(v)+'.png')) self.bomb_mImages.append(pygame.image.load('./feiji/image'+str(v)+'.png')) #记录爆炸位置 self.x=0 self.y=0 defauto_move(self): """自动移动""" #向下移动 self.rect.bottom+=self.speed #如果飞机向下移出边界删除它 ifself.rect.top>Manager.height: self.kill() #按不同方向左右移动 ifself.direction=='right': self.rect.right+=6 elifself.direction=='left': self.rect.right-=6 #超出左右边界更改移动方向 ifself.rect.right>=Manager.width: self.direction='left' ifself.rect.left<=0: self.direction='right' defauto_fire(self): #用一个随机数 num=random.randint(1,40) #判断如果等于1就发射一个子弹,降低了概率 ifnum==5: #生成敌机子弹 bullet=EnemyBullet(self.screen,self.rect.left,self.rect.top) #添加到精灵组 self.bullets.add(bullet) #把子弹添加到类的all_bullets里用来碰撞检测 EnemyPlane.all_bullets.add(bullet) defbomb(self): """显示爆炸图片""" ifself.mIndex>=len(self.bomb_mImages): #播放到了最后爆炸结束返回True returnTrue self.screen.blit(self.bomb_mImages[self.mIndex],(self.x,self.y)) self.mIndex+=1 defupdate(self): ifself.is_remove: ifself.rect.left!=-200: #记录爆炸时的位置 self.x=self.rect.left self.y=self.rect.top #如果已经被击中把飞机移除窗口防止继续碰撞检测 self.rect.left=-200 self.rect.top=-200 #显示爆炸效果 ifself.bomb()andnotself.bullets: #如果爆炸结束把自己从精灵组删除 self.kill() else: #移动 self.auto_move() #开火 self.auto_fire() #显示 self.display() self.bullet_show() defdisplay(self): #把飞机显示到窗口上飞机116*100 self.screen.blit(self.image,self.rect) defbullet_show(self): ifself.bullets: #敌机子弹更新 self.bullets.update() #敌机子弹显示 self.bullets.draw(self.screen) classEnemyBullet(pygame.sprite.Sprite): #path_num表示散弹中子弹是哪一个 def__init__(self,screen,x,y): #调用父类初始化方法 #pygame.sprite.Sprite.__init__(self) super().__init__() #窗口 self.screen=screen #一个子弹图片 self.image=pygame.image.load('./feiji/bullet_6.png') #子弹矩形区域对象 self.rect=self.image.get_rect() #子弹左上角坐标 self.rect.topleft=[x+40,y+60] #子弹的速度 self.speed=10 defupdate(self): """修改子弹坐标""" self.rect.bottom+=self.speed #如果子弹向下移出边界删除它 ifself.rect.top>Manager.height: self.kill() #游戏音乐 classGameSound(object): def__init__(self): pygame.mixer.init()#音乐模块初始化 pygame.mixer.music.load("./feiji/Jamesketed.mp3") pygame.mixer.music.set_volume(0.5)#声音大小一半 self.__bomb=pygame.mixer.Sound("./feiji/bomb.wav") defplayBackgroundMusic(self): #开始播放背景音乐-1表示一直重复播放 pygame.mixer.music.play(-1) defplayBombSound(self): pygame.mixer.Sound.play(self.__bomb)#爆炸音乐 classGameBackground(object): #初始化地图 def__init__(self,screen): self.mImage1=pygame.image.load("./feiji/img_bg_level_4.jpg") self.mImage2=pygame.image.load("./feiji/img_bg_level_4.jpg") #窗口 self.screen=screen #辅助移动地图 self.y1=0 self.y2=-Manager.height#-768 defupdate(self): self.move() self.draw() #移动地图 defmove(self): self.y1+=2 self.y2+=2 ifself.y1>=Manager.height: self.y1=0 ifself.y2>=0: self.y2=-Manager.height #绘制地图 defdraw(self): self.screen.blit(self.mImage1,(0,self.y1)) self.screen.blit(self.mImage2,(0,self.y2)) classManager: hero:HeroPlane #创建宽高 width=512 height=768 def__init__(self): #pygame初始化否则找不到字体文件 pygame.init() #1创建一个窗口参数1是宽高,参数2附加参数参3是颜色深度 self.screen=pygame.display.set_mode((self.width,self.height),0,32) #2创建背景图的对象 #self.background=pygame.image.load('./feiji/img_bg_level_5.jpg') self.background=GameBackground(self.screen) #创建飞机对象 self.hero=HeroPlane(self.screen) #创建时钟对象 self.clock=pygame.time.Clock() #敌机的精灵组 self.enemys=pygame.sprite.Group() #初始化音效对象 self.sound=GameSound() #定义分数属性 self.score=0 #倒计时时间 self.over_time=3 defexit(self): #执行退出代码 pygame.quit() #程序的退出 exit() defnew_enemy(self): #创建敌机对象 enemy=EnemyPlane(self.screen) #添加到精灵组 self.enemys.add(enemy) defdrawText(self,text,x,y,textHeight=30,fontColor=(255,255,255),backgroudColor=None): #通过字体文件获得字体对象参数1字体文件参数2字体大小 font_obj=pygame.font.Font('./feiji/baddf.ttf',textHeight) #1文字2是否抗锯齿3文字颜色4背景颜色 text_obj=font_obj.render(text,True,fontColor,backgroudColor)#配置要显示的文字 #获得要显示的对象的rect text_rect=text_obj.get_rect() #设置显示对象的坐标 text_rect.topleft=(x,y) #绘制字到指定区域参1是文字对象参2矩形对象 self.screen.blit(text_obj,text_rect) defgame_over_timer(self): """执行倒计时""" self.over_time-=1 ifself.over_time==0: #停止倒计时 pygame.time.set_timer(Constants.game_over_id,0) #重新开始游戏 self.start_game() defshow_over_text(self): print('self.over_time',self.over_time) #游戏结束显示倒计时时间 self.drawText('gameover%d'%self.over_time,0,Manager.height/2,textHeight=50, fontColor=[0,0,0]) defstart_game(self): globalmanager #情况敌机子弹的精灵组 EnemyPlane.all_bullets.empty() manager=Manager() #垃圾回收提示python解释器要回收了 gc.collect() manager.main() defmain(self): #播放背景音乐 self.sound.playBackgroundMusic() #参1eventid是事件id,自己定义(0-32之间)不要和已用的pygame的其它事件id冲突, #参2是定时事件的间隔时间,单位是毫秒 pygame.time.set_timer(Constants.new_enemy,500) whileTrue: #控制每s执行的次数 self.clock.tick(60) #获取事件并且处理 foreventinpygame.event.get(): #判断事件的类型是否是退出 ifevent.type==pygame.QUIT: #退出 self.exit() elifevent.type==Constants.new_enemy: #等于20说明定时器生效添加一个敌机 #print('添加一个敌机') self.new_enemy() elifevent.type==Constants.game_over_id: print('倒计时33333') #显示倒计时时间 self.game_over_timer() #3把背景图显示到窗口上 #self.screen.blit(self.background,(0,0)) self.background.update() self.drawText('分数:%s'%self.score,0,0) ifself.hero: self.drawText('血量:%s'%self.hero.blood_value,0,30) #更新飞机 self.hero.update() #ifself.hero.blood_value<=0andnotself.hero.bullets.sprites(): ##把玩家飞机引用指向None尽快释放 #self.hero=None else: self.drawText('血量:0',0,30) #更新敌机 self.enemys.update() #如果飞机已经挂掉就一直显示倒计时 ifnotself.hero: #显示倒计时 self.show_over_text() #判断玩家飞机和敌机是否都存在self.enemys.sprites()返回精灵组对应的精灵列表 ifself.heroandself.enemys.sprites(): #碰撞检测返回的碰撞到的敌机列表 collide_enemys=pygame.sprite.spritecollide(self.hero,self.enemys,False,pygame.sprite.collide_mask) ifcollide_enemys: #如果列表不为空说明碰到了敌机 print('碰到了敌机') #爆炸声音 self.sound.playBombSound() self.hero.kill_blood(100) forenemy_itemincollide_enemys: #标记敌机已经被撞到 enemy_item.is_remove=True #判断玩家飞机和玩家飞机的子弹和敌机是否都存在 ifself.heroandself.hero.bulletsandself.enemys: #检测玩家飞机的子弹和敌机的碰撞 #返回是个字典格式{<Bulletsprite(in0groups)>:[<EnemyPlanesprite(in0groups)>]} #{碰撞的子弹1:[打中的敌机1,打中的敌机2],碰撞的子弹2:[打中的敌机1,打中的敌机5]} collode_dict=pygame.sprite.groupcollide(self.hero.bullets,self.enemys,True,False, pygame.sprite.collide_mask) #1多个子弹打中同一个飞机#2不同子弹打中不同飞机#所有加分值时要去除重复的敌机 #print(collode_dict) ifcollode_dict: #爆炸声音 self.sound.playBombSound() print(self.score) #用一个集合添加敌机去除重复的 enemyset=set() #获取所有打中的敌机列表,然后遍历 forv_enemysincollode_dict.values(): #遍历敌机列表 forenemy_iteminv_enemys: #print(id(enemy_item)) enemyset.add(enemy_item) #标记敌机已经被击中 enemy_item.is_remove=True #碰撞后+10分*集合里敌机的数量 self.score+=10*len(enemyset) #判断玩家飞机和和敌机子弹 ifself.heroandEnemyPlane.all_bullets: #检测玩家和敌机子弹的碰撞 collide_bullets=pygame.sprite.spritecollide(self.hero,EnemyPlane.all_bullets,True, pygame.sprite.collide_mask) ifcollide_bullets: #如果碰到了就减少10*子弹数量的血量 self.hero.kill_blood(10*len(collide_bullets)) #2显示窗口 pygame.display.update() if__name__=='__main__': manager=Manager() manager.main()
看完上述内容,你们掌握使用python制作一个飞机大战游戏的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注恰卡编程网行业资讯频道,感谢各位的阅读!
推荐阅读
-
Python中怎么动态声明变量赋值
这篇文章将为大家详细讲解有关Python中怎么动态声明变量赋值,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文...
-
python中变量的存储原理是什么
-
Python中怎么引用传递变量赋值
这篇文章将为大家详细讲解有关Python中怎么引用传递变量赋值,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文...
-
python中怎么获取程序执行文件路径
python中怎么获取程序执行文件路径,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的...
-
Python中如何获取文件系统的使用率
Python中如何获取文件系统的使用率,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴...
-
Python中怎么获取文件的创建和修改时间
这篇文章将为大家详细讲解有关Python中怎么获取文件的创建和修改时间,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读...
-
python中怎么获取依赖包
今天就跟大家聊聊有关python中怎么获取依赖包,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据...
-
python怎么实现批量文件加密功能
-
python中怎么实现threading线程同步
小编给大家分享一下python中怎么实现threading线程同步,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!...
-
python下thread模块创建线程的方法
本篇内容介绍了“python下thread模块创建线程的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来...