|
|
3 years ago | |
|---|---|---|
| README.md | 3 years ago | |
README.md
dafeiji
import pygame from pygame import * import time import random
#########敌方飞机类 class Enemyplane(pygame.sprite.Sprite): #用精灵类构建组存放敌机所有子弹 enemy__bullets = pygame.sprite.Group()
def __init__(self,screen):
# 这个精灵的初始化方法 必须调用
pygame.sprite.Sprite.__init__(self)
# 2创造飞机图片
self.player = pygame.image.load("D:/python/资料/飞机大战/feiji/enemy0.png")
# 根据图片image获取矩形对象‘
self.rect = self.player.get_rect() # rect:矩形
x = random.randrange(1,Manage.bg_size[0],50)
self.rect.topleft = [x ,0]
# 飞机速度
self.speed = 7
#窗口
self.screen = screen
#创建一个敌方子弹列表
self.bullets = pygame.sprite.Group()
#方向
self.fangxiang = 'right'
def auto_move(self):
#判断移动方向
if self.fangxiang == 'right':
self.rect.right += self.speed
if self.fangxiang == 'left':
self.rect.left -= self.speed
if self.rect.right >Manage.bg_size[0]:
self.fangxiang = 'left'
if self.rect.left <0:
self.fangxiang = 'right'
self.rect.bottom+=self.speed
def autofire(self):
#降低子弹频率
random_num = random.randint(1,15)
if random_num == 8:
# 自动发射子弹
self.bullet = EnemyBullet(self.screen, self.rect.left, self.rect.top)
self.bullets.add(self.bullet)
Enemyplane.enemy__bullets.add(self.bullet)
def display(self):
# 将飞机贴在窗口
self.screen.blit(self.player, self.rect)
#更新子弹坐标
self.bullets.update()
#把所有子弹添加到屏幕
self.bullets.draw(self.screen)
def update(self):
self.auto_move()
self.autofire()
self.display()
@classmethod
def clear_bullets(cls):
#清空子弹
cls.enemy__bullets.empty()
########玩家飞机类 class Heroplane(pygame.sprite.Sprite): #用精灵类创建一个装玩家子弹的组(用于歼灭敌机) bullets = pygame.sprite.Group()
i = 0
def __init__(self,screen):
#这个精灵的初始化方法 必须调用
pygame.sprite.Sprite.__init__(self)
# 2创造飞机图片
self.player = pygame.image.load("D:/python/资料/飞机大战/feiji/hero1.png")
#根据图片image获取矩形对象‘
self.rect = self.player.get_rect() #rect:矩形
self.rect.topleft = [Manage.bg_size[0]/2-100/2,600]
# 飞机速度
self.speed = 10
#窗口
self.screen = screen
#创建一个精灵列表对像
self.bullets = pygame.sprite.Group()
def key_control(self):
# 监听键盘事件
key_pressed = pygame.key.get_pressed()
if key_pressed[K_w] or key_pressed[K_UP]:
self.rect.top -= self.speed
#判断是否上下超出边界
if self.rect.top<0:
self.rect.top=0
if self.rect.bottom>Manage.bg_size[1]:
self.rect.bottom=Manage.bg_size[1]
if key_pressed[K_a] or key_pressed[K_LEFT]:
self.rect.left -= self.speed
#判断是否左右超出边界
if self.rect.left <0:
self.rect.left = 0
if self.rect.right>Manage.bg_size[0]:
self.rect.right = Manage.bg_size[0]
if key_pressed[K_d] or key_pressed[K_RIGHT]:
self.rect.right += self.speed
# 判断是否超出边界
if self.rect.left < 0:
self.rect.left = 0
if self.rect.right > Manage.bg_size[0]:
self.rect.right = Manage.bg_size[0]
if key_pressed[K_s] or key_pressed[K_DOWN]:
self.rect.bottom += self.speed
if self.rect.top<0:
self.rect.top=0
if self.rect.bottom>Manage.bg_size[1]:
self.rect.bottom=Manage.bg_size[1]
if key_pressed[K_SPACE]:
Heroplane.i+=1
if Heroplane.i ==15:
#创建子弹对象
self.bullet = Bullet(self.screen,self.rect.left,self.rect.top)
#将子弹对象加入子弹列表
self.bullets.add(self.bullet)
Heroplane.bullets.add(self.bullet)
Heroplane.i = 0
def display(self):
# 将飞机贴在窗口
self.screen.blit(self.player, self.rect)
#更新子弹坐标
self.bullets.update()
#把所有子弹全部添加到屏幕
self.bullets.draw(self.screen)
def update(self):
self.key_control()
self.display()
@classmethod
def clear_bullets(cls):
#清空子弹
cls.bullets.empty()
##########玩家子弹类 class Bullet(pygame.sprite.Sprite): def init(self, screen , x , y): # 这个精灵的初始化方法 必须调用 pygame.sprite.Sprite.init(self)
#导入子弹图片
self.image = pygame.image.load("D:/python/资料/飞机大战/feiji/bullet.png")
#获取矩形对象
self.rect = self.image.get_rect()
self.rect.topleft = [x+100/2-22/2,y-22]
#窗口
self.screen = screen
#速度
self.speed = 10
def update(self):
#修改子弹坐标
self.rect.top -= self.speed
#如果子弹超出屏幕上方,则销毁子弹对象
if self.rect.top<-22:
self.kill()
############敌方子弹类 class EnemyBullet(pygame.sprite.Sprite): def init(self, screen , x , y): # 这个精灵的初始化方法 必须调用 pygame.sprite.Sprite.init(self)
#导入子弹图片
self.image = pygame.image.load("D:/python/资料/飞机大战/feiji/bullet-1.gif")
#获取矩形对象
self.rect = self.image.get_rect()
self.rect.topleft = [x+50/2-8/2,y+39]
#窗口
self.screen = screen
#速度
self.speed = 10
def update(self):
#修改子弹坐标
self.rect.top += self.speed
#如果子弹超出屏幕上方,则销毁子弹对象
if self.rect.top>Manage.bg_size[1]:
self.kill()
############创建音乐类 class gamesound: def init(self): #音乐模块初始化 pygame.mixer.init() #导入音乐 pygame.mixer.music.load('D:/python/资料/飞机大战/feiji/bg2.ogg') #设置声音大小 pygame.mixer.music.set_volume(0.4)
#导入爆炸音效
self.__bomb = pygame.mixer.Sound("D:/python/资料/飞机大战/feiji/bomb.wav")
def playBackgroundmusic(self):
#无限循环播放背景音乐
pygame.mixer.music.play(-1)
def playBombSound(self):
pygame.mixer.Sound.play(self.__bomb)
#########爆炸类 class Bomb: #初始化爆炸 def init(self,screen,type): self.screen = screen if type =='enemy': #加载爆炸资源 self.mImages = [pygame.image.load(f"D:/python/资料/飞机大战/feiji/enemy0_down{str(v)}.png") for v in range(1,5)] else: #加载爆炸资源 self.mImages = [pygame.image.load(f"D:/python/资料/飞机大战/feiji/hero_blowup_n{str(v)}.png") for v in range(1,5)]
#设置当前爆炸索引
self.mIndex = 0
#爆炸位置
self.mpos = [0,0]
#是否可见
self.mvisible = False
#设置位置
def action(self,rect):
#触发爆炸方法draw
#爆炸坐标
self.mpos[0] = rect.left
self.mpos[1] = rect.top
#打开爆炸的开关
self.mvisible = True
#绘制爆炸
def draw(self):
if not self.mvisible:
return
self.screen.blit(self.mImages[self.mIndex],(self.mpos[0],self.mpos[1]))
self.mIndex+=1
if self.mIndex >= len(self.mImages):
#如果图片加载到最后,代表爆炸结束
#下标重置
self.mIndex = 0
self.mvisible = False
#########创建地图类 class map(): def init(self,screen): #导入两张相同的图片 self.background1 = pygame.image.load("D:/python/资料/飞机大战/feiji/img_bg_level_1.jpg") self.background2 = pygame.image.load("D:/python/资料/飞机大战/feiji/img_bg_level_1.jpg") #窗口 self.screen = screen #辅助移动地图 self.y1 = 0 self.y2 = -Manage.bg_size[1] #-768
#移动地图
def move(self):
self.y1 +=2
self.y2 +=2
if self.y1>=Manage.bg_size[1]:
self.y1 = 0
self.y2 = -Manage.bg_size[1]
#绘制地图
def draw_map(self):
self.screen.blit(self.background1,(0,self.y1))
self.screen.blit(self.background2,(0,self.y2))
class Manage(): bg_size = (512,768)
#游戏结束,倒计时的id
game_over_id = 11
#游戏是否结束
is_game_over = False
#创建敌机定时器的id
creat_enemy_id = 10
#倒计时时长
over_time = 3
def __init__(self):
# pygame 初始化(绘制文字需要)
pygame.init()
# 创建一个窗口
self.screen = pygame.display.set_mode(Manage.bg_size, 0, 32)
#调用地图
self.map = map(self.screen)
#初始化一个装玩家精灵的group
self.players = pygame.sprite.Group()
#初始化一个装敌机精灵的group
self.enemys = pygame.sprite.Group()
#初始化一个玩家爆炸的对象
self.player_bomb = Bomb(self.screen,'player')
#初始化一个地方爆炸的对象
self.enemy_bomb = Bomb(self.screen,"enemy")
#初始化一个声音播放的对象
self.sound = gamesound()
def exit(self):
print("退出")
pygame.quit()
exit()
def show_over_text(self):
self.drawText('game over %d' % Manage.over_time , 100, Manage.bg_size[1]/2,textHeight=50,fontColor=[255,0,0])
def game_over_timer(self):
self.show_over_text()
#倒计时-1
Manage.over_time -=1
if Manage.over_time == 0:
#定时停止
pygame.time.set_timer(Manage.game_over_id,0)
#倒计时结束后重新开始
Manage.over_time = 3
Manage.is_game_over = False
self.start_game()
def start_game(self):
#重新开始游戏,有些类属性要清空
Enemyplane.clear_bullets()
Heroplane.clear_bullets()
manager = Manage()
manager.mian()
def new_player(self):
#创建玩家飞机对象,添加到玩家组
player = Heroplane(self.screen)
self.players.add(player)
def new_enemy(self):
#创建敌方飞机对象,添加到敌机组
enemy =Enemyplane(self.screen)
self.enemys.add(enemy)
#绘制文字
def drawText(self,text,x,y, textHeight = 30, fontColor=(255,0,0),backgroudColor = None):
#通过字体文件获取字体对象
font_obj = pygame.font.Font("D:/python/资料/飞机大战/feiji/baddf.ttf",textHeight)
#配置要显示的文字
text_obj = font_obj.render(text,True,fontColor,backgroudColor)
#获取要显示对象的rect
text_rect = text_obj.get_rect()
#设置显示对象的坐标
text_rect.topleft = (x,y)
#绘制文字到指定区域
self.screen.blit(text_obj,text_rect)
def mian(self):
#播放背景音乐
self.sound.playBackgroundmusic()
#创建一个玩家
self.new_player()
#开启创建敌机的定时器
pygame.time.set_timer(Manage.creat_enemy_id,1000)
while True:
#移动地图
self.map.move()
self.map.draw_map()
#绘制文字
self.drawText("hp:10",0,0) #要求在Manage类里初始化pygame
if Manage.is_game_over:
#判断游戏结束才显示结束文字
self.show_over_text()
#遍历所有事件
for event in pygame.event.get():
# 判断事件类型
if event.type == pygame.QUIT:
self.exit()
elif event.type ==Manage.creat_enemy_id:
#创建一个敌机
self.new_enemy()
elif event.type == Manage.game_over_id:
#定时器触发的事件
self.game_over_timer()
#判断玩家飞机和敌机碰撞(只能判断两个精灵组之间的碰撞)
iscollide1 = pygame.sprite.groupcollide(self.players,self.enemys,True,True)
if iscollide1:
Manage.is_game_over = True #标志着游戏的结束
pygame.time.set_timer(Manage.game_over_id,1000) #开启游戏倒计时
items = list(iscollide1.items())[0]
print(items)
x = items[0]
y = items[1][0]
#玩家爆炸图片
self.player_bomb.action(x.rect)
#敌机爆炸图片
self.enemy_bomb.action(y.rect)
# 播放爆炸音效
self.sound.playBombSound()
#玩家子弹和敌方飞机的碰撞(歼灭敌机)
iscollide2 = pygame.sprite.groupcollide(Heroplane.bullets,self.enemys,True,True)
if iscollide2:
items = list(iscollide2.items())[0]
y = items[1][0]
#敌方飞机爆炸图片
self.enemy_bomb.action(y.rect)
# 播放爆炸音效
self.sound.playBombSound()
#敌机子弹和己方飞机的碰撞(己方被灭)
if self.players.sprites():
isover = pygame.sprite.spritecollide(self.players.sprites()[0],Enemyplane.enemy__bullets,True)
if isover:
Manage.is_game_over = True #标示着游戏结束
pygame.time.set_timer(Manage.game_over_id,1000) #开始游戏倒计时
#玩家飞机爆炸特效
self.player_bomb.action(self.players.sprites()[0].rect)
#把玩家从精灵组移除
self.players.remove(self.players.sprites()[0])
# 播放爆炸音效
self.sound.playBombSound()
#绘制爆炸特效
self.player_bomb.draw()
self.enemy_bomb.draw()
#玩家飞机和子弹的显示