正常运行一小段时间后敌机和子弹都会出现重影
并且程序不断报错
libpng warning: iCCP: known incorrect sRGB profile
下面是源代码
import random import pygame from pygame import * import time # 玩家飞机类 class PlayerPlane(pygame.sprite.Sprite): # 存放所有飞机子弹的组 bullets = pygame.sprite.Group() def __init__(self, screen): # 这个精灵的初始化方法 pygame.sprite.Sprite.__init__(self) # 创建一个图片,当作玩家飞机 self.player = pygame.image.load('./aircraft/player.png') # 根据图片获取矩形对象 self.rect = self.player.get_rect() self.rect.topleft = [Manager.bg_size[0] / 2 - 102 / 2,550] # 飞机的速度 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 key_pressed[K_s] or key_pressed[K_DOWN]: self.rect.bottom += self.speed if key_pressed[K_a] or key_pressed[K_LEFT]: self.rect.left -= self.speed if key_pressed[K_d] or key_pressed[K_RIGHT]: self.rect.right += self.speed if key_pressed[K_SPACE]: # 按下空格发射子弹 bullet = Bullet(self.screen, self.rect.left, self.rect.top) # 把子弹装入弹夹 self.bullets.add(bullet) # 存放所有飞机子弹的组 PlayerPlane.bullets.add(bullet) def update(self): self.key_control() self.display() def display(self): # 将飞机图片贴入窗口中 self.screen.blit(self.player, self.rect) # 更新所有子弹坐标 self.bullets.update() # 把所有子弹添加到屏幕 self.bullets.draw(self.screen) @classmethod def clear_bullets(cls): # 清空子弹 cls.bullets.empty() # 敌方飞机类 class EnemyPlane(pygame.sprite.Sprite): # 存放所有敌机子弹的组 enemy_bullets = pygame.sprite.Group() def __init__(self, screen): # 这个精灵的初始化方法 pygame.sprite.Sprite.__init__(self) # 创建一个图片,当作敌方飞机 self.enemy = pygame.image.load('./aircraft/enemy1.png') # 根据图片获取矩形对象 self.rect = self.enemy.get_rect() x = random.randrange(1,Manager.bg_size[0],50) self.rect.topleft = [x,0] # 飞机的速度 self.speed = 5 self.screen = screen # 装子弹的列表(弹夹) self.bullets = pygame.sprite.Group() # 敌机移动方向 self.direction = 'right' def display(self): # 将飞机图片贴入窗口中 self.screen.blit(self.enemy, self.rect) # 更新所有子弹坐标 self.bullets.update() # 把所有子弹添加到屏幕 self.bullets.draw(self.screen) def auto_move(self): if self.direction == 'right': self.rect.right += self.speed else: self.rect.right -= self.speed if self.rect.right > Manager.bg_size[0] - 57: self.direction = 'left' elif self.rect.right < 0: self.direction = 'right' self.rect.bottom += self.speed def auto_fire(self): random_number = random.randint(1, 15) if random_number == 8: bullet = EnemyBullet(self.screen, self.rect.right, self.rect.top) self.bullets.add(bullet) # 把子弹添加到类属性的子弹组里 EnemyPlane.enemy_bullets.add(bullet) def update(self): self.auto_move() self.auto_fire() self.display() @classmethod def clear_bullets(cls): # 清空子弹 cls.enemy_bullets.empty() # 子弹类 class Bullet(pygame.sprite.Sprite): def __init__(self, screen, x, y): # 精灵类初始化 pygame.sprite.Sprite.__init__(self) # 图片 self.image = pygame.image.load('./aircraft/bullet.png') # 获取矩形对象 self.rect = self.image.get_rect() self.rect.topleft = [x + 102 / 2 - 5 / 2,y - 11] # 窗口 self.screen = screen # 发射速度 self.speed = 10 def update(self): # 修改子弹坐标 self.rect.top -= self.speed # 如果子弹移出屏幕,则销毁子弹对象 if self.rect.top < -11: self.kill() # 敌方子弹类 class EnemyBullet(pygame.sprite.Sprite): def __init__(self, screen, x, y): # 精灵类初始化 pygame.sprite.Sprite.__init__(self) # 图片 self.image = pygame.image.load('./aircraft/bullet1.png') # 获取矩形对象 self.rect = self.image.get_rect() self.rect.topleft = [x + 52 / 2 - 4 / 2, y + 43 - 11 / 2] # 窗口 self.screen = screen # 发射速度 self.speed = 10 def update(self): # 修改子弹坐标 self.rect.top += self.speed # 如果子弹移出屏幕,则销毁子弹对象 if self.rect.top > Manager.bg_size[1]: self.kill() class GameMusic(object): def __init__(self): pygame.mixer.init() # 音乐模块初始化 pygame.mixer.music.load('./aircraft/game_music.ogg') pygame.mixer.music.set_volume(0.5) self._bomb = pygame.mixer.Sound('./aircraft/enemy1_down.wav') def playGameMusic(self): pygame.mixer.music.play(-1) # 开始播放音乐 def playBombSound(self): pygame.mixer.Sound.play(self._bomb) class Bomb(object): # 初始化碰撞 def __init__(self,screen,type): self.screen = screen if type == 'enemy': self.mImage = [pygame.image.load('./aircraft/enemy1_down' + str(v) + '.png') for v in range(1 , 5)] else: self.mImage = [pygame.image.load('./aircraft/me_destroy_' + str(v) + '.png') for v in range(1, 5)] # 设置当前爆炸播放索引 self.mIdex = 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): while self.mVisible: for image in self.mImage: self.screen.blit(image, self.mPos) pygame.display.flip() self.mVisible = False # 地图 class GameBackground(object): # 初始化地图 def __init__(self,screen): self.mImage1 = pygame.image.load('./aircraft/background.png') self.mImage2 = pygame.image.load('./aircraft/background.png') # 窗口 self.screen = screen # 辅助移动地图 self.y1 = 0 self.y2 = -Manager.bg_size[1] # 使地图动起来 def move(self): self.y1 += 2 self.y2 += 2 if self.y1 >= Manager.bg_size[1]: self.y1 = 0 if self.y2 >= 0: self.y1 = -Manager.bg_size[1] # 绘制地图 def draw(self): self.screen.blit(self.mImage1,(0,self.y1)) self.screen.blit(self.mImage2, (0, self.y2)) def update(self): self.move() self.draw() class Manager(object): pygame.display.set_caption('飞机大战') bg_size = (480,700) # 创建敌机定时器的id create_enemy_id = 22 # 游戏结束 倒计时的id game_over_id = 10 # 游戏是否结束 is_game_over = False # 倒计时时间 over_time = 3 def __init__(self): pygame.init() # 创建一个窗口,用于显示内容 self.screen = pygame.display.set_mode(Manager.bg_size, 0, 32) # 创建一个和窗口一样大的图片,用于充当背景 # self.background = pygame.image.load('./aircraft/background.png') self.map = GameBackground(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 = GameMusic() def exit(self): print('退出') pygame.quit() exit() def show_over_text(self): # 游戏结束 倒计时结束后重新开始 self.drawText('Game Over %d' % Manager.over_time,100,Manager.bg_size[1]/2,textHight=45,fontColor=(0,0,0)) def game_over_timer(self): self.show_over_text() # 倒计时-1 Manager.over_time -= 1 if Manager.over_time == 0: # 参数2为0时 定时间停止 pygame.time.set_timer(Manager.game_over_id,0) # 倒计时结束后重新开始 Manager.over_time = 3 Manager.is_game_over = False self.start_game() def start_game(self): # 重新开始游戏,有些类的属性要清空 EnemyPlane.clear_bullets() PlayerPlane.clear_bullets() manager = Manager() manager.main() def new_player(self): # 创建飞机对象 添加到玩家组里 player = PlayerPlane(self.screen) self.players.add(player) def new_enemy(self): # 创建敌机对象 添加到敌机组里 enemy = EnemyPlane(self.screen) self.enemys.add(enemy) # 绘制文字 def drawText(self,text,x,y,textHight = 20,fontColor = (0,0,0),backgroundColor = None): # 通过字体文件获取字体对象 font_obj = pygame.font.Font('./aircraft/font.ttf',textHight) # 配置要显示的文字 text_obj = font_obj.render(text,True,fontColor,backgroundColor) # 获取要显示的文字的rect text_rect = text_obj.get_rect() # 设置显示对象的坐标 text_rect.topleft = (x,y) # 绘制字到指定区域 self.screen.blit(text_obj,text_rect) def main(self): # 播放背景音乐 self.sound.playGameMusic() # 创建一个玩家 self.new_player() # 开启创建敌机的定时器 pygame.time.set_timer(Manager.create_enemy_id,1000) while True: # 将背景图片贴入窗口中 # self.screen.blit(self.background, (0, 0)) # 使地图移动 self.map.move() # 把地图贴到窗口上 self.map.draw() # 绘制文字 self.drawText('hp : 1000000',0,0) if Manager.is_game_over: # 判断游戏结束 才显示文字 self.show_over_text() # 遍历所有事件 for event in pygame.event.get(): # 判断事件类型 if event.type == QUIT: # 执行退出 self.exit() elif event.type == Manager.create_enemy_id: # 创建一个敌机 self.new_enemy() elif event.type == Manager.game_over_id: # 定时器触发的事件 self.game_over_timer() # 调用爆炸事件 self.player_bomb.draw() self.enemy_bomb.draw() # 玩家飞机和敌机子弹的判断 if self.players.sprites(): isover = pygame.sprite.spritecollide(self.players.sprites()[0],EnemyPlane.enemy_bullets,True) if isover: Manager.is_game_over = True # 游戏结束 pygame.time.set_timer(Manager.game_over_id,1000) # 开始游戏倒计时 print('你已中弹') self.player_bomb.action(self.players.sprites()[0].rect) # 把玩家飞机从精灵族移除 self.players.remove((self.players.sprites()[0])) # 爆炸的声音 self.sound.playBombSound() # 判断碰撞 iscollide = pygame.sprite.groupcollide(self.players,self.enemys,True,True) if iscollide: Manager.is_game_over = True # 标志游戏结束 pygame.time.set_timer(Manager.game_over_id,1000) # 开启游戏倒计时 items = list(iscollide.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() # 玩家子弹和所有敌机的碰撞判断 iscollide1 = pygame.sprite.groupcollide(PlayerPlane.bullets,self.enemys,True,True) if iscollide1: items = list(iscollide1.items())[0] y = items[1][0] # 敌机爆炸图片 self.enemy_bomb.action(y.rect) # 爆炸的声音 self.sound.playBombSound() # 玩家飞机和子弹的显示 self.players.update() # 敌机和子弹的显示 self.enemys.update() # 刷新窗口内容 pygame.display.update() time.sleep(0.01) if __name__ == '__main__': manager = Manager() manager.main()
劳驾大佬们看看问题出在哪?