使用python制作一个飞机大战游戏

使用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制作一个飞机大战游戏的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注恰卡编程网行业资讯频道,感谢各位的阅读!

发布于 2021-03-21 22:37:55
收藏
分享
海报
0 条评论
170
上一篇:this与super怎么在java项目中使用 下一篇:怎么在java中使用Locks
目录

    推荐阅读

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码