def main(): # # 基本变量 RED = (255, 0, 0) WHITE = (255, 255, 255) GREEN = (0, 255, 0) BLACK = (0, 0, 0) score = 0 level = 1 switch_alpha = 255 life_number = 3 index = [0, 0, 0, 0, 0, 0, 0] # 包含玩家,小型敌人,中型敌人,大型敌人,初级子弹的索引, 双倍子弹索引, 载入游戏图片索引 global delay, last_bomb, enemy_numbers, bullet_supply_numbers, bomb_supply_numbers, \ double_bullet_time, volume_cond, volume, volume_2 # #开关变量 # 制造飞机动态变化的开关 switch_image = True # 变化透明度的开关 switch_alpha_cond = True # 生成双倍子弹开关 is_double_bullet = False # 游戏开始界面的开关 START = True # 游戏运行开关 Running = True # 游戏结束画面的开关 END = True # 按钮变换的开关 button_switch = False button_2_switch = False # 读取历史纪录的开关 read_score = True # 音量开关 volume_cond = True # # 生成定时器模块 # 双倍子弹计时器 DOUBLE_BULLET_TIME = USEREVENT pygame.time.set_timer(DOUBLE_BULLET_TIME, 0 * 1000) # 我方无敌状态计时器 WD_TIME = USEREVENT + 1 pygame.time.set_timer(WD_TIME, 0 * 1000) # 显示历史分数的定时器 DISPLAY_SCORE_TIME = USEREVENT + 2 pygame.time.set_timer(DISPLAY_SCORE_TIME, 5 * 1000) # # 生成按钮对象 # 生成暂停按钮对象 pause_cond = False pause_switch = False paused_rect = paused_nor_image.get_rect() paused_rect.left, paused_rect.top = width_2 // 2 - paused_rect.width // 2, heigth_2 - paused_rect.height - 8 # 生成炸弹按钮对象 bomb_image_rect = bomb_image.get_rect() bomb_image_rect.left, bomb_image_rect.top = paused_rect.right + 50, paused_rect.top - 5 # 生成音量按键对象 music_switch = False music_image_rect = music_play_image.get_rect() music_image_rect.left, music_image_rect.top = width_2 - music_image_rect.width - 10, 66 # 生成作者按键对象 author_image = author_nor_image authon_image_rect = author_image.get_rect() authon_image_rect.left, authon_image_rect.top = width_2 - authon_image_rect.width - 10, 66 + 20 + music_image_rect.height # 生成设置按钮对象 setting_image = setting_nor_image setting_rect = setting_image.get_rect() setting_rect.left, setting_rect.top = width_2 - setting_rect.width - 10, 66 + 40 + authon_image_rect.height + music_image_rect.height # 生成停止界面选项 button_rect = button_not_image.get_rect() button_2_rect = button_not_image.get_rect() button_3_rect = button_not_image.get_rect() resume_font_rect = resume_font_image.get_rect() restart_font_rect = restart_font_image.get_rect() quit_font_rect = quit_font_image.get_rect() # # 生成对象模块组 # 生成飞机对象模块 player_plane = myplane.MyPlane(screen_2_size, screen) # 玩家个人飞机 # 生成敌方飞机的模块 enemies = pygame.sprite.Group() # 敌人总数组 small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, int(enemy_numbers[0])) mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, int(enemy_numbers[1])) big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, int(enemy_numbers[2])) # 生成初级子弹模块 bullet_1 = [] bullet_1_numbers = 5 midtop = list(player_plane.rect.midtop) midtop[0] -= 10 midtop[1] -= 12 for n in range(bullet_1_numbers): bullet_1.append(bullets.Bullet_1(midtop)) # 生成双倍子弹模块 bullet_2 = [] bullet_2_numbers = 10 double_time = double_bullet_time left_button_pos = player_plane.rect.centerx - 33, player_plane.rect.centery - 25 right_button_pos = player_plane.rect.centerx + 33, player_plane.rect.centery - 25 for n in range(bullet_2_numbers): bullet_2.append(bullets.Bullet_2(left_button_pos)) bullet_2.append(bullets.Bullet_2(right_button_pos)) bullet_list = [] # 生成道具模块 supplies = pygame.sprite.Group() bullet_supply = supply.BulletSupply(screen, screen_2_size) supplies.add(bullet_supply) bomb_supply = supply.BombSupply(screen, screen_2_size) supplies.add(bomb_supply) SUPPLY_TIME = USEREVENT pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) # 游戏的初始画面 while START: pygame.display.set_caption("飞机大战--MGod吾 v1.0") for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: action_image.set_alpha(0) display_loading(index[6], delay) pygame.display.set_mode(screen_2_size) start_music.stop() START = False # 绘制屏幕 if pygame.display.get_active(): start_music.play() action_image.set_alpha(switch_alpha) name_image_rect = name_image.get_rect() action_image_rect = action_image.get_rect() screen.blit(start_bg_image, (0, 0)) screen.blit(action_image, (width_1 // 2 - action_image_rect.width // 2, 400)) screen.blit(name_image, (width_1 // 2 - name_image_rect.width // 2, 100)) if not (delay % 5): if switch_alpha_cond: if switch_alpha > 0: switch_alpha -= 3 else: switch_alpha_cond = not switch_alpha_cond else: if 255 - switch_alpha > 0: switch_alpha += 3 else: switch_alpha_cond = not switch_alpha_cond else: start_music.stop() # 刷新屏幕 pygame.display.update() pygame.display.flip() clock.tick(fps) # 游戏人口 while Running: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: if volume_cond: button_sound.play() pause_cond = not pause_cond if pause_cond: pygame.time.set_timer(SUPPLY_TIME, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: pygame.mixer.music.unpause() pygame.mixer.unpause() pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) elif event.key == pygame.K_q: if last_bomb: last_bomb -= 1 if volume_cond: use_bomb_sound.play() for enemy in enemies: if enemy.rect.bottom > 0: enemy.hp = 0 elif event.key == pygame.K_e: if volume_cond: button_sound.play() volume_cond = not volume_cond elif event.key == pygame.K_r: if volume_cond: button_sound.play() dispaly_author() elif event.key == pygame.K_t: if volume_cond: button_sound.play() setting(volume, volume_2) elif event.type == DOUBLE_BULLET_TIME and is_double_bullet and not pause_cond: if double_time: double_time -= 1 elif event.type == WD_TIME: player_plane.wd = False elif event.type == SUPPLY_TIME: if choice([True, False]): bullet_supply.active = True bullet_supply.start_pos() else: bomb_supply.active = True bomb_supply.start_pos() elif event.type == pygame.MOUSEMOTION: if paused_rect.collidepoint(event.pos): pause_switch = True else: pause_switch = False if button_rect.collidepoint(event.pos): button_switch = True else: button_switch = False if button_2_rect.collidepoint(event.pos): button_2_switch = True else: button_2_switch = False if music_image_rect.collidepoint(event.pos): music_switch = True else: music_switch = False if authon_image_rect.collidepoint(event.pos): author_image = author_pressed_image else: author_image = author_nor_image if setting_rect.collidepoint(event.pos): setting_image = setting_pressed_image else: setting_image = setting_nor_image elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1 and paused_rect.collidepoint(event.pos): if volume_cond: button_sound.play() pause_cond = not pause_cond elif event.button == 1 and button_rect.collidepoint(event.pos): if volume_cond: button_sound.play() pause_cond = not pause_cond elif event.button == 1 and button_2_rect.collidepoint( event.pos): if volume_cond: button_sound.play() pygame.quit() exit() elif event.button == 1 and music_image_rect.collidepoint( event.pos): volume_cond = not volume_cond elif event.button == 1 and bomb_image_rect.collidepoint( event.pos): if last_bomb: last_bomb -= 1 if volume_cond: use_bomb_sound.play() for enemy in enemies: if enemy.rect.bottom > 0: enemy.hp = 0 elif event.button == 1 and authon_image_rect.collidepoint( event.pos): if volume_cond: button_sound.play() dispaly_author() elif event.button == 1 and setting_rect.collidepoint( event.pos): if volume_cond: button_sound.play() setting(volume, volume_2) # 检测键盘按键事件 key_pressed = pygame.key.get_pressed() if key_pressed[pygame.K_UP] or key_pressed[pygame.K_w]: player_plane.moveUP() elif key_pressed[pygame.K_DOWN] or key_pressed[pygame.K_s]: player_plane.moveDOWN() elif key_pressed[pygame.K_LEFT] or key_pressed[pygame.K_a]: player_plane.moveLEFT() elif key_pressed[pygame.K_RIGHT] or key_pressed[pygame.K_d]: player_plane.moveRIGHT() midtop = list(player_plane.rect.midtop) midtop[0] -= 10 midtop[1] -= 12 # 用于调整尾气切换的模块 delay -= 1 if not delay: delay = 100 if not (delay % 5): switch_image = not switch_image screen.blit(bg_image, (0, 0)) # 检测暂停按钮与恢复按钮的状态 if not pause_cond: pause_image_1 = paused_nor_image pause_image_2 = paused_pressed_image else: pause_image_1 = resume_nor_image pause_image_2 = resume_pressed_image if not pause_switch: screen.blit(pause_image_1, paused_rect) else: screen.blit(pause_image_2, paused_rect) # 检测音量按键的状态 if volume_cond: music_image_1 = music_play_image music_image_2 = music_play_image2 else: music_image_1 = music_stop_image music_image_2 = music_stop_image2 # 绘制得分项 score_font = font.render(f"Score: {str(score)}", True, BLACK) screen.blit(score_font, (10, 5)) # 绘制炸弹道具数量统计 screen.blit(bomb_image, bomb_image_rect) last_bomb_font = font.render(f" x{str(last_bomb)}", True, BLACK) screen.blit(last_bomb_font, (bomb_image_rect.right + 5, bomb_image_rect.top + 10)) # 绘制音量, 作者详情,设置按键 if not music_switch: screen.blit(music_image_1, music_image_rect) else: screen.blit(music_image_2, music_image_rect) screen.blit(author_image, authon_image_rect) screen.blit(setting_image, setting_rect) # 绘制玩家生命剩余 if life_number: for n in range(1, life_number + 1): screen.blit(life_image, ((width_2 // 2) // (life_number + 1) * n - 28, heigth_2 - 50)) if is_double_bullet and not pause_cond: # 绘制双倍子弹剩余时间 if double_time > 3: double_time_font = font.render(f"{str(double_time)}", True, BLACK) else: double_time_font = font.render(f"{str(double_time)}", True, RED) d_time_rect = double_time_font.get_rect() pygame.draw.circle( screen, WHITE, (width_2 - 41 + d_time_rect.centerx, 8 + d_time_rect.centery), 25) screen.blit(double_time_font, (width_2 - 40, 10)) if not double_time: is_double_bullet = False pygame.time.set_timer(DOUBLE_BULLET_TIME, 0) # 依据得分改变游戏难度 if score > 150000: if level == 1: level += 1 add_number = [5, 3, 2] # 小:15,中:8,大:4 add_small_enemies(small_enemies, enemies, add_number[0]) add_mid_enemies(mid_enemies, enemies, add_number[1]) add_big_enemies(big_enemies, enemies, add_number[2]) elif score > 500000: if level == 2: level += 1 add_number = [10, 8, 5] # 小:25,中:16,大:9 add_small_enemies(small_enemies, enemies, add_number[0]) add_mid_enemies(mid_enemies, enemies, add_number[1]) add_big_enemies(big_enemies, enemies, add_number[2]) elif score > 10000000: if level == 3: level += 1 add_number = [10, 8, 5] # 小:35,中:24,大:14 add_small_enemies(small_enemies, enemies, add_number[0]) add_mid_enemies(mid_enemies, enemies, add_number[1]) add_big_enemies(big_enemies, enemies, add_number[2]) # 当窗口呈现时并且暂停按钮不被按下时所要执行的代码 if pygame.display.get_active(): if not pause_cond: if volume_cond: pygame.mixer.music.unpause() else: pygame.mixer.music.pause() pygame.mixer.music.unpause() pygame.display.set_caption("正在游戏") # 检测玩家飞机是否与敌方飞机相撞 bump_numbers = pygame.sprite.spritecollide( player_plane, enemies, False, pygame.sprite.collide_mask) if bump_numbers and not player_plane.wd: if life_number: life_number -= 1 if volume_cond: user_getover.play() player_plane.start_pos() pygame.time.set_timer(WD_TIME, 3 * 1000) for e in bump_numbers: if not e.hp: e.hp = 0 # 判断玩家飞机是否存活 if life_number: if switch_image: screen.blit(player_plane.plane_1, player_plane.rect) else: screen.blit(player_plane.plane_2, player_plane.rect) else: if not index[0]: if volume_cond: user_getover.play() if not (delay % 5): screen.blit(player_plane.getover_image_list[index[0]], player_plane.rect) index[0] = (index[0] + 1) % 4 if not index[0]: pygame.mixer.pause() pygame.mixer.music.pause() pygame.time.delay(1 * 1000) break # 发射子弹模块 if not is_double_bullet: bullet_list = bullet_1 if not (delay % 10): bullet_1[index[4]].start_pos(midtop) index[4] = (index[4] + 1) % bullet_1_numbers elif not (delay % 10) and life_number: if volume_cond: bullet_sound.play() else: bullet_list = bullet_2 if not (delay % 8): bullet_2[index[5]].start_pos( (player_plane.rect.centerx - 33, player_plane.rect.centery - 25)) bullet_2[index[5] + 1].start_pos( (player_plane.rect.centerx + 30, player_plane.rect.centery - 25)) index[5] = (index[5] + 2) % bullet_2_numbers elif not (delay % 8) and life_number: if volume_cond: bullet_sound.play() # 检测子弹是否存活 for bullet in bullet_list: if bullet.active: screen.blit(bullet.bullet_image, bullet.rect) bullet.move() enemies_hit = pygame.sprite.spritecollide( bullet, enemies, False, pygame.sprite.collide_mask) if enemies_hit: bullet.active = False for enemy in enemies_hit: enemy.hit = True if enemy.hp != 0: enemy.hp -= 1 # 检测道具是否被获得 get_supply = pygame.sprite.spritecollide( player_plane, supplies, False, pygame.sprite.collide_mask) if get_supply: for s in get_supply: if s == bomb_supply: if volume_cond: get_bomb_sound.play() if last_bomb < 3: last_bomb += 1 elif s == bullet_supply: if volume_cond: get_bomb_sound.play() double_time = double_bullet_time is_double_bullet = True pygame.time.set_timer(DOUBLE_BULLET_TIME, 1 * 1000) s.active = False s.start_pos() # 生成道具模块 if bullet_supply.active: bullet_supply.appear() bullet_supply.move() if bomb_supply.active: bomb_supply.appear() bomb_supply.move() # 生成敌方战舰 for enemy in small_enemies: if enemy.hp: enemy.appear() enemy.move() elif not (delay % 3): score += 500 if index[1] == 0: if volume_cond: enemy0_down_sound.play() screen.blit(enemy.getover_image_list[index[1]], enemy.rect) index[1] = (index[1] + 1) % 4 if index[1] == 0: enemy.start_pos() for enemy in mid_enemies: if enemy.hp: if enemy.hit: enemy.hit = False enemy.get_hit() else: enemy.appear() enemy.move() elif not (delay % 3): score += 2000 if index[2] == 0: if volume_cond: enemy1_down_sound.play() screen.blit(enemy.getover_image_list[index[2]], enemy.rect) index[2] = (index[2] + 1) % 4 if index[2] == 0: enemy.start_pos() # 绘制血条 pygame.draw.line(screen, WHITE, (enemy.rect.left, enemy.rect.bottom + 5), (enemy.rect.right, enemy.rect.bottom + 5), 2) percent_hp = enemy.hp / 5 if percent_hp > 0.2: hp_color = GREEN else: hp_color = RED pygame.draw.line( screen, hp_color, (enemy.rect.left, enemy.rect.bottom + 5), (enemy.rect.left + enemy.rect.width * percent_hp, enemy.rect.bottom + 5), 2) for enemy in big_enemies: if enemy.hp: if enemy.rect.bottom == -40: enemy2_appear_sound.play(-1) if enemy.hit: enemy.hit = False enemy.get_hit() elif switch_image: enemy.switchimage1() else: enemy.switchimage2() enemy.move() elif not (delay % 3): score += 50000 enemy2_appear_sound.stop() if index[3] == 0: if volume_cond: enemy2_down_sound.play() screen.blit(enemy.getover_image_list[index[3]], enemy.rect) index[3] = (index[3] + 1) % 6 if index[3] == 0: enemy.start_pos() # 绘制血条 pygame.draw.line(screen, WHITE, (enemy.rect.left, enemy.rect.bottom + 5), (enemy.rect.right, enemy.rect.bottom + 5), 2) percent_hp = enemy.hp / 15 if percent_hp > 0.2: hp_color = GREEN else: hp_color = RED pygame.draw.line( screen, hp_color, (enemy.rect.left, enemy.rect.bottom + 5), (enemy.rect.left + enemy.rect.width * percent_hp, enemy.rect.bottom + 5), 2) else: if not button_switch: button_image_1 = button_not_image else: button_image_1 = button_pressed_image if not button_2_switch: button_image_2 = button_not_image else: button_image_2 = button_pressed_image button_rect.left, button_rect.top = width_2 // 2 - button_rect.width // 2, 180 button_2_rect.left, button_2_rect.top = width_2 // 2 - button_rect.width // 2, 180 + button_2_rect.height + 50 resume_font_rect.center = button_rect.center quit_font_rect.center = button_2_rect.center screen.blit(button_image_1, button_rect) screen.blit(button_image_2, button_2_rect) screen.blit(resume_font_image, resume_font_rect) screen.blit(quit_font_image, quit_font_rect) pygame.display.set_caption("暂停游戏") else: pause_cond = True pygame.mixer.music.pause() pygame.mixer.pause() # 刷新屏幕 pygame.display.update() pygame.display.flip() clock.tick(fps) # 玩家死亡的画面 while END: if read_score: history_score = config["score"].getint("history_score") read_score = False # pygame.display.set_caption("游戏结束") is_most = set_history_score(score, history_score) screen.blit(get_over_image, (0, -80)) history_score_font = font_2.render(str(history_score), True, BLACK) history_score_rect = history_score_font.get_rect() screen.blit(history_score_font, (width_2 // 2 - history_score_rect.width // 2, 200)) if is_most: now_score_font = font_2.render(str(score), True, GREEN) else: now_score_font = font_2.render(str(score), True, RED) now_score_rect = now_score_font.get_rect() screen.blit(now_score_font, (width_2 // 2 - now_score_rect.width // 2, 520)) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() elif event.type == pygame.KEYDOWN: pygame.display.set_mode(screen_1_size) read_score = True main() break # 刷新屏幕 pygame.display.update() pygame.display.flip() clock.tick(fps)
def define_game_vars(self): # 实例我方飞机 self.me = myplane.MyPlane() # 实例敌方飞机 self.enemies = pygame.sprite.Group() # 实例敌方小型飞机 self.small_enemies = pygame.sprite.Group() add_small_enemies(self.small_enemies, self.enemies, 15) # 实例敌方中型飞机 self.mid_enemies = pygame.sprite.Group() add_mid_enemies(self.mid_enemies, self.enemies, 4) # 实例敌方大型飞机 self.big_enemies = pygame.sprite.Group() add_big_enemies(self.big_enemies, self.enemies, 2) # 实例普通子弹 self.bullet_normal = [] self.bullet_normal_index = 0 self.bullet_normal_num = GlobalVar.BULLET_NORMAL_NUMBER for i in range(self.bullet_normal_num): self.bullet_normal.append(bullet.Bullet1(self.me.rect.midtop)) # 实例超级子弹 self.bullet_super = [] self.bullet_super_index = 0 self.bullet_super_num = GlobalVar.BULLET_SUPER_NUMBER for i in range(self.bullet_super_num // 2): self.bullet_super.append( bullet.Bullet2( (self.me.rect.centerx - 33, self.me.rect.centery))) self.bullet_super.append( bullet.Bullet2( (self.me.rect.centerx + 30, self.me.rect.centery))) # 中弹图片索引 self.e1_destroy_index = 0 self.e2_destroy_index = 0 self.e3_destroy_index = 0 self.me_destroy_index = 0 # 统计得分 self.score = 0 # 标志是否暂停游戏 self.paused = False self.paused_rect = self.paused_nor_image.get_rect() self.paused_rect.left = GlobalVar.SYSTEM_SCREEN_WIDTH - self.paused_rect.width - 10 self.paused_rect.top = 10 self.paused_image = self.paused_nor_image # 设置难度 self.level = GlobalVar.LEVEL1 # 全屏炸弹 self.bomb_rect = self.bomb_image.get_rect() self.bomb_num = GlobalVar.SYSTEM_BOMB_NUMBER # 每30秒发放一个补给包 self.bullet_supply = supply.BulletSupply() self.bomb_supply = supply.BombSupply() self.supply_time = USEREVENT pygame.time.set_timer(self.supply_time, GlobalVar.SYSTEM_SUPPLY_TIME) # 超级子弹定时器 self.double_bullet_time = USEREVENT + 1 # 解除我方重生无敌定时器 self.invincible_time = USEREVENT + 2 # 标志是否使用超级子弹 self.is_double_bullet = False # 生命数量 self.life_rect = self.life_image.get_rect() self.life_num = GlobalVar.SYSTEM_LIFE_NUMBER # 用于切换我方飞机图片 self.switch_plane = True # 游戏结束画面 self.again_rect = self.again_image.get_rect() self.gameover_rect = self.gameover_image.get_rect() # 用于延迟切换 self.delay = GlobalVar.SYSTEM_DELAY # 限制打开一次记录文件 self.recorded = False self.clock = pygame.time.Clock() self.running = True
def main(): global background global bg clock1 = pygame.time.Clock() # 实例化我方飞机 me = myPlane.Myplane(bg_size) # 绘制得分 score = 0 best_score = 0 score_font = pygame.font.Font("font/font.TTF", 32) font = pygame.font.Font('font/font.ttf', 36) game_over_font = pygame.font.Font('font/font.ttf', 50) # 实例化补给包 bomb_supply = supply.BombSupply(bg_size) bullet_supply = supply.SuperbulletSupply(bg_size) SUPPLY_TIME = USEREVENT pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) #是否切换速度 transform = True #暂停敌机移动 is_move = True # 实例化子弹 bullet1 = [] bullet1_index = 0 BULLET1_NUM = 4 for i in range(BULLET1_NUM): bullet1.append(bullet.Bullet(me.rect.midtop)) # 生成超级子弹 bullet2 = [] bullet2_index = 0 BULLET2_NUM = 4 for i in range(BULLET2_NUM): bullet2.append(bullet.SuperBullet(me.rect.midtop)) #设置能量条 m = 1000 mp = m // 20 # 设置超级子弹定时器 SUPER_BULLET_TIME = USEREVENT + 1 # 是否使用超级子弹 is_super_bullet = False # 设置无敌 INVICIBLE_TIME = USEREVENT + 2 # 设置分数记录 recorded = False # 难度增加标志 level = 1 level_font = pygame.font.Font("font/font.ttf", 32) # 设置全屏炸弹 bomb_image = pygame.image.load("image/bomb.png").convert_alpha() bomb_rect = bomb_image.get_rect() bomb_font = pygame.font.Font("font/font.ttf", 32) bomb_num = 5 # 所有敌机放到一个组里面,用于判断和我机是否碰撞 enemies = pygame.sprite.Group() # 生成小型敌机 small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, 15) # 生成中型敌机 mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, 5) # 生成大型敌机 big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 2) # 生成BOSS bosses = pygame.sprite.Group() boss = enemy.Boss(bg_size) enemies.add(boss) bosses.add(boss) # 飞机毁灭状态索引 small_plane_destroy = 0 mid_plane_destroy = 0 big_plane_destroy = 0 # boss_plane_destroy = 0 my_plane_destroy = 0 # 设置暂停标志 paused = False # 设置我方飞机次数 life_image = pygame.image.load("image/lifeimage.png").convert_alpha() life_rect = life_image.get_rect() life_font = pygame.font.Font("font/font.ttf", 32) life_num = 5 # 设置飞机动态效果 switch_image = True # 设置延时参数 delay = 100 # 暂停图片 pause_pressed_image = pygame.image.load("image/pause.png").convert_alpha() pause_nor_image = pygame.image.load("image/pause_nor.png").convert_alpha() pause_rect = pause_nor_image.get_rect() pause_rect.left, pause_rect.top = (width - pause_rect.width) // 2, \ (height - pause_rect.height) // 2 pause_image = pause_nor_image # 我方飞机无敌效果 shields = shield.Shield() # 游戏结束字体设置 quit_text = font.render("QUIT", True, WHITE) again_text = font.render("Again", True, WHITE) quit_pos = quit_text.get_rect() again_pos = again_text.get_rect() quit_pos.left = width // 3 - quit_pos.width // 2 quit_pos.top = height // 2 + 150 again_pos.left = width // 3 * 2 - again_pos.width // 2 again_pos.top = height // 2 + 150 #设置背景索引 bg = 1 # 设置作弊次数 fade_time = 1 # 游戏帧率设置 clock = pygame.time.Clock() # 游戏开始标志 running = True # 设置开头游戏介绍 while running: for event in pygame.event.get(): if event.type == QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN or event.type == KEYDOWN: running = False start = pygame.image.load("image/start.png").convert_alpha() screen.blit(start, (0, 0)) pygame.display.flip() clock.tick(30) # 主程序开始 key_pressed = pygame.key.get_pressed() running = True while running: for event in pygame.event.get(): if event.type == QUIT: sys.exit() elif life_num > 0 and event.type == MOUSEBUTTONDOWN: if event.button == 1: paused = not paused if paused: pygame.time.set_timer(SUPPLY_TIME, 0) # pygame.time.set_timer(SUPER_BULLET_TIME,0) pygame.mixer.music.pause() pygame.mixer.pause() # 绘制暂停按钮 else: pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) pygame.mixer.music.unpause() pygame.mixer.unpause() #screen.blit(pause_image, pause_rect) elif event.type == MOUSEMOTION: if pause_rect.collidepoint(event.pos): pause_image = pause_nor_image else: pause_image = pause_pressed_image elif event.type == KEYDOWN: if event.key == K_SPACE: if bomb_num: bomb_num -= 1 for each in enemies: if each.rect.bottom > 0: boss.energy -= 200 each.active = False if key_pressed[K_x] and key_pressed[K_k] and key_pressed[K_q]: if fade_time == 1: life_num += 2 fade_time -= 1 if life_num > 5: life_num = 5 elif event.type == SUPPLY_TIME: supply_sound.play() if choice([False, True]): bomb_supply.reset() else: bullet_supply.reset() elif event.type == SUPER_BULLET_TIME: is_super_bullet = False pygame.time.set_timer(SUPER_BULLET_TIME, 0) elif event.type == INVICIBLE_TIME: me.invicible = False pygame.time.set_timer(INVICIBLE_TIME, 0) # gameover之后玩家的选择 elif life_num == 0 and event.type == MOUSEBUTTONDOWN: mouse_pos = event.pos # 玩家选择退出 if quit_pos.left < mouse_pos[0] < quit_pos.right and \ mouse_pos[1] > quit_pos.top and \ mouse_pos[1] < quit_pos.bottom: sys.exit() # 玩家选择再玩 if mouse_pos[0] > again_pos.left and \ mouse_pos[0] < again_pos.right and \ mouse_pos[1] > again_pos.top and \ mouse_pos[1] < again_pos.bottom: # 重设背景并播放背景音乐同时关闭gameover音效 background = pygame.image.load( 'image/bgimage.png').convert() pygame.mixer.stop() pygame.mixer.music.play(-1) #重设背景图片 bg = 1 # 重设分数 score = 0 # 重新生成敌机 enemies = pygame.sprite.Group() small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, 15) mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, 5) big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 2) # 重设全屏炸弹数量及玩家生命数,重设我方飞机 bomb_num = 5 life_num = 5 me.reset() pygame.time.set_timer(INVICIBLE_TIME, 3000) # 开启补给包,超级子弹判断重设 pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) is_supper_bullet = False # 重设飞机毁灭恢复参数 big_plane_destroy = 0 middle_plane_destroy = 0 small_plane_destroy = 0 my_plane_destroy = 0 # 其他设定 fade_time = 1 switch_image = True delay = 100 paused = False level = 1 recorded = False #背景音乐图片切换 if bg == 1: screen.blit(background, (0, 0)) if bg == 2: screen.blit(level2, (0, 0)) if bg == 3: screen.blit(level3, (0, 0)) if bg == 4: screen.blit(level4, (0, 0)) if bg == 5: screen.blit(level5, (0, 0)) if level == 1 and score >= 10000: if transform: bg = 2 # 增加3架小飞机,1架中飞机,1架大飞机 add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) #增加小型敌机速度 inc_speed(small_enemies, 1) transform = False #去掉所有飞机ddddddd is_move = False boss.reset() if not boss.active: #level = 2 is_move = True #复活到原地等待 boss._return() transform = True score += 20000 shield.active = False me.invicible = False # inc_speed(mid_enemies,1) # inc_speed(big_enemies,1) elif level == 2 and score >= 200000: level = 3 bg = 3 # 增加3架小飞机,1架中飞机,1架大飞机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) inc_speed(small_enemies, 1) inc_speed(mid_enemies, 1) # inc_speed(big_enemies,1) elif level == 3 and score >= 300000: level = 4 bg = 4 # 增加3架小飞机,1架中飞机,1架大飞机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) inc_speed(small_enemies, 1) inc_speed(mid_enemies, 1) inc_speed(big_enemies, 1) elif level == 4 and score >= 400000: level = 5 bg = 5 # 增加3架小飞机,1架中飞机,1架大飞机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) inc_speed(small_enemies, 1) inc_speed(mid_enemies, 1) inc_speed(big_enemies, 1) # print(enemies.speed) # 绘制BOSS敌机,随机移动 elif level == 5 and score >= 1000000: # 增加3架小飞机,1架中飞机,1架大飞机 del_enemies(small_enemies, enemies) del_enemies(mid_enemies, enemies) del_enemies(big_enemies, enemies) if life_num > 0 and not paused: key_pressed = pygame.key.get_pressed() # 设置我方飞机动作 if key_pressed[K_w] or key_pressed[K_UP]: me.moveUp() if key_pressed[K_s] or key_pressed[K_DOWN]: me.moveDown() if key_pressed[K_a] or key_pressed[K_LEFT]: me.moveLeft() if key_pressed[K_d] or key_pressed[K_RIGHT]: me.moveRight() # 检测飞机是否碰撞 enemies_down = pygame.sprite.spritecollide( me, enemies, False, pygame.sprite.collide_mask) if enemies_down and not me.invicible: me.active = False for e in enemies_down: e.active = False # 绘制大型敌机 for each in big_enemies: if each.active: each.move() if switch_image: screen.blit(each.image1, each.rect) else: screen.blit(each.image2, each.rect) # 绘制血槽 pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5), \ (each.rect.right, each.rect.top - 5), \ 2) energy_remain = each.energy / enemy.BigEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + each.rect.width * energy_remain, \ each.rect.top - 5), 2) if each.rect.bottom >= -50: pass # e3_fly_sound.play() else: # 毁灭 if big_plane_destroy == 0: bigenemydown_sound.play() screen.blit(each.destroy_image, each.rect) big_plane_destroy = (big_plane_destroy + 1) % 2 if big_plane_destroy == 0: each.reset() score += 50000 e3_fly_sound.stop() # 绘制中型敌机 for each in mid_enemies: if each.active: each.move() screen.blit(each.image, each.rect) # 绘制血槽 pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5), \ (each.rect.right, each.rect.top - 5), \ 2) energy_remain = each.energy / enemy.MidEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + each.rect.width * energy_remain, \ each.rect.top - 5), 2) else: if mid_plane_destroy == 0: midenemydown_sound.play() screen.blit(each.destroy_image, each.rect) mid_plane_destroy = (mid_plane_destroy + 1) % 2 if mid_plane_destroy == 0: score += 50000 each.reset() # 绘制小型敌机 for each in small_enemies: if each.active: each.move() screen.blit(each.image, each.rect) else: if small_plane_destroy == 0: smallenemydown_sound.play() screen.blit(each.destroy_image, each.rect) small_plane_destroy = (small_plane_destroy + 1) % 2 if small_plane_destroy == 0: score += 1000 each.reset() # 绘制我方飞机 if me.active: if switch_image: screen.blit(me.myplane_image1, me.rect) else: screen.blit(me.myplane_image2, me.rect) else: # 毁灭 screen.blit(me.myplane_image1, me.rect) if not (delay % 10): if my_plane_destroy == 0: myplanedown_sound.play() screen.blit(me.destroy_image, me.rect) my_plane_destroy = (my_plane_destroy + 1) % 4 if my_plane_destroy == 0: life_num -= 1 if life_num > 0: me.reset() sheilds.reset() if sheilds.active == True: sheilds.move((me.rect.left - 26, me.rect.top - 6)) pygame.time.set_timer(INVICIBLE_TIME, 3 * 1000) # 每10帧绘制子弹 # 绘制全屏炸弹并检测是否获得 if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, me): getbomb_sound.play() if bomb_num < 5: bomb_num += 1 bomb_supply.active = False # 绘制超级子弹并检测是否获得 if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, me): getbullet_sound.play() is_super_bullet = True pygame.time.set_timer(SUPER_BULLET_TIME, 18 * 1000) bullet_supply.active = False if is_super_bullet: if not (delay % 10): bullets = bullet2 bullets[bullet2_index].reset(me.rect.midtop) bullet2_sound.play() bullet2_index = (bullet2_index + 1) % BULLET2_NUM else: if not (delay % 10): bullets = bullet1 bullet1[bullet1_index].reset(me.rect.midtop) bullet1_sound.play() bullet1_index = (bullet1_index + 1) % BULLET1_NUM # 检测子弹击中目标 for b in bullets: if b.active: b.move() screen.blit(b.image, b.rect) enemy_hit = pygame.sprite.spritecollide( b, enemies, False, pygame.sprite.collide_mask) # boss_bullet_hit = pygame.sprite.spritecollide(boss,b,False) if enemy_hit: b.active = False for e in enemy_hit: if e in mid_enemies or e in big_enemies: e.energy -= (2 if is_super_bullet else 1) if e.energy == 0: e.active = False else: e.active = False if bosses: for each in bosses: if each.active: each.move() if each.hit: screen.blit(each.image_hit, each.rect) each.hit = False else: screen.blit(each.image, each.rect) # 绘制血槽 pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top + 4), \ (each.rect.right, each.rect.top + 4)) # 当生命大于20%显示绿色,否则显示红色 energy_remain = each.energy / enemy.Boss.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top + 4), \ (each.rect.left + each.rect.width * energy_remain, \ each.rect.top + 4), 4) else: if not transform: position = each.rect.center # # 原地生成一个随机奖励 # if not choice(range(lv_dict[5])): # prize_bomb = supply.Bomb1(size, position) # _prize_bomb.add(prize_bomb) # # if not choice(range(lv_dict[5])): # prize_life = _plane.Life(size, position) # _prize_life.add(prize_life) # # _delay = 0 if not is_move: for each in enemies: if each not in bosses: each.reset() elif paused: # 绘制暂停按钮 screen.blit(pause_image, pause_rect) if life_num > 0: # 绘制全屏炸弹 bomb_text = bomb_font.render("X %d " % bomb_num, True, GREEN) text1_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text1_rect.height)) # 显示次数 """life_text = life_font.render("X %d" % life_num,True,GREEN) text2_rect = life_text.get_rect() screen.blit(life_image,(250,height - 10 - life_rect.height)) screen.blit(life_text,(250 + life_rect.width,height - 5 - text2_rect.height)) """ if life_num: for i in range(life_num): screen.blit(life_image, \ (width - 10 - (i + 1) * life_rect.width, \ height - 10 - life_rect.height)) # 显示关卡等级 level_text = level_font.render("level = %d " % level, True, GREEN) text2_rect = level_text.get_rect() screen.blit(level_text, (10, 30)) # 显示得分 score_text = score_font.render("Score: %s" % str(score), True, GREEN) screen.blit(score_text, (10, 5)) elif life_num == 0: # 绘制游戏结束界面 game_over = game_over_font.render("GAME OVER", True, WHITE) screen.blit(game_over, ((width - game_over.get_width()) // 2, \ (height - game_over.get_height()) // 2)) pygame.mixer.music.stop() pygame.time.set_timer(SUPPLY_TIME, 0) # 记录历史最高得分 if not recorded: with open("record.data", "r") as f: temp = f.read() if temp != "": best_score = int(temp) if best_score < score: best_score = score with open("record.data", "w") as f: f.write(str(best_score)) recorded = True pygame.mixer.stop() game_over_sound.play() background = pygame.image.load( 'image/gameover.png').convert() # 绘制分数,最高分和当前分数 best_score_text = font.render('Best Score: %s' % str(best_score), True, WHITE) screen.blit(best_score_text, (40, 50)) your_score_text = font.render('Your Score: %s' % str(score), True, WHITE) screen.blit(score_text, ((width - your_score_text.get_width()) // 2 + 50, \ (height + game_over.get_height()) // 2 - 150)) # 绘制选择项 screen.blit(quit_text, quit_pos) screen.blit(again_text, again_pos) mouse_pos = pygame.mouse.get_pos() # 退出Quit if mouse_pos[0] > quit_pos.left and mouse_pos[0] < quit_pos.right and \ mouse_pos[1] > quit_pos.top and mouse_pos[1] < quit_pos.bottom: quit_text = font.render("Quit", True, RED) else: quit_text = font.render("Quit", True, WHITE) # 重新Again if mouse_pos[0] > again_pos.left and mouse_pos[0] < again_pos.right and \ mouse_pos[1] > again_pos.top and mouse_pos[1] < again_pos.bottom: again_text = font.render("Again", True, GREEN) else: again_text = font.render("Again", True, WHITE) if not (delay % 5): switch_image = not switch_image delay -= 1 if not delay: delay == 100 pygame.display.flip() clock.tick(60)
def main(): pygame.mixer.music.play(-1) global background #游戏分数 best_score = 0 your_score = 0 #字体 font = pygame.font.Font('font/font.ttf', 36) game_over_font = pygame.font.Font('font/font.ttf', 50) #生成我方飞机 me = myPlane.MyPlane(bg_size) #生成敌方飞机 enemies = pygame.sprite.Group() small_planes = pygame.sprite.Group() add_small_planes(small_planes, enemies, 15) middle_planes = pygame.sprite.Group() add_middle_planes(middle_planes, enemies, 5) big_planes = pygame.sprite.Group() add_big_planes(big_planes, enemies, 2) #生成子弹 bullet1 = [] bullet1_index = 0 BULLET1_NUM = 4 for i in range(BULLET1_NUM): bullet1.append(bullet.Bullet1(me.rect.midtop)) #生成超级子弹 bullet2 = [] bullet2_index = 0 BULLET2_NUM = 4 for i in range(BULLET2_NUM): bullet2.append(bullet.Bullet2(me.rect.midtop)) #全屏炸弹 bomb_image = pygame.image.load('image/bomb.png').convert_alpha() bomb_rect = bomb_image.get_rect() bomb_rect.left = 0 bomb_rect.bottom = bg_height bomb_num = 3 #玩家生命 life_image = pygame.image.load('image/myPlaneLife.png').convert_alpha() life_rect = life_image.get_rect() life_rect.left = bg_width // 2 life_rect.bottom = bg_height life_num = 3 #补给包 bomb_supply = supply.BombSupply(bg_size) bullet_supply = supply.BulletSupply(bg_size) #补给包定时器,设定每30秒发放一次补给包 SUPPLY_TIME = USEREVENT pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) #超级子弹定时器 SUPPER_BULLET_TIME = USEREVENT + 1 is_supper_bullet = False #我方飞机无敌定时器 MY_PLANE_INVINCIBLE_TIME = USEREVENT + 2 #记录飞机毁灭之后隔多久重置 big_plane_destroy = 0 middle_plane_destroy = 0 small_plane_destroy = 0 my_plane_destroy = 0 #用于切换图片 switch_image = True #用于延迟 delay = 100 #游戏暂停 paused = False pause_image = pygame.image.load('image/pause.png').convert_alpha() pause_rect = pause_image.get_rect() pause_rect.left = bg_width // 2 - pause_rect.width // 2 pause_rect.top = bg_height // 2 - pause_rect.height // 2 #游戏难度级别 level = 1 #用于防止重复打开记录文件 recorded = False #游戏结束后的选项及其属性 quit_text = font.render('Quit', True, WHITE) again_text = font.render('Again', True, WHITE) quit_pos = quit_text.get_rect() again_pos = again_text.get_rect() quit_pos.left = bg_width // 3 - quit_pos.width // 2 quit_pos.top = bg_height // 2 + 150 again_pos.left = bg_width // 3 * 2 - again_pos.width // 2 again_pos.top = bg_height // 2 + 150 clock = pygame.time.Clock() running = True #绘制前言介绍 while running: for event in pygame.event.get(): if event.type == QUIT: sys.exit() elif event.type == KEYDOWN: running = False info = pygame.image.load('image/info.jpg').convert() screen.blit(info, (0, 0)) pygame.display.flip() clock.tick(30) #游戏正式开始 running = True while running: for event in pygame.event.get(): if event.type == QUIT: sys.exit() #点击鼠标游戏暂停 elif life_num > 0 and event.type == MOUSEBUTTONDOWN: paused = not paused if paused:#暂停游戏时关闭音乐音效和补给 pygame.time.set_timer(SUPPLY_TIME, 0) pygame.mixer.music.pause() pygame.mixer.pause() else:#非暂停状态则重新开启资源 pygame.time.set_timer(SUPPLY_TIME, 30) pygame.mixer.music.unpause() pygame.mixer.unpause() #空格引爆全屏炸弹 elif event.type == KEYDOWN and \ life_num > 0 and \ not paused: if event.key == K_SPACE and bomb_num > 0: bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0:#炸毁对象必须出现在屏幕中 each.is_alive = False #每30秒随机发放一个补给包 elif event.type == SUPPLY_TIME: if random.choice([True, False]): bomb_supply.reset() else: bullet_supply.reset() #开启超级子弹18秒后自动关闭 elif event.type == SUPPER_BULLET_TIME: is_supper_bullet = False pygame.time.set_timer(SUPPER_BULLET_TIME, 0) #重生3秒后关闭无敌状态 elif event.type == MY_PLANE_INVINCIBLE_TIME: me.invincible = False pygame.time.set_timer(MY_PLANE_INVINCIBLE_TIME, 0) #gameover之后玩家的选择 elif life_num == 0 and event.type == MOUSEBUTTONDOWN: mouse_pos = event.pos #玩家选择退出 if mouse_pos[0] > quit_pos.left and \ mouse_pos[0] < quit_pos.right and \ mouse_pos[1] > quit_pos.top and \ mouse_pos[1] < quit_pos.bottom: sys.exit() #玩家选择再玩 if mouse_pos[0] > again_pos.left and \ mouse_pos[0] < again_pos.right and \ mouse_pos[1] > again_pos.top and \ mouse_pos[1] < again_pos.bottom: #重设背景并播放背景音乐同时关闭gameover音效 background = pygame.image.load('image/background.jpg').convert() pygame.mixer.stop() pygame.mixer.music.play(-1) #重设分数 your_score = 0 #重新生成敌机 enemies = pygame.sprite.Group() small_planes = pygame.sprite.Group() add_small_planes(small_planes, enemies, 15) middle_planes = pygame.sprite.Group() add_middle_planes(middle_planes, enemies, 5) big_planes = pygame.sprite.Group() add_big_planes(big_planes, enemies, 2) #重设全屏炸弹数量及玩家生命数,重设我方飞机 bomb_num = 3 life_num = 3 me.reset() pygame.time.set_timer(MY_PLANE_INVINCIBLE_TIME, 3000) #开启补给包,超级子弹判断重设 pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) is_supper_bullet = False #重设飞机毁灭恢复参数 big_plane_destroy = 0 middle_plane_destroy = 0 small_plane_destroy = 0 my_plane_destroy = 0 #其他设定 switch_image = True delay = 100 paused = False level = 1 recorded = False #根据用户得分增加游戏难度 if level == 1 and your_score > 50000: level = 2 #增加3加小型敌机,2架中型敌机,1加大型敌机 add_small_planes(small_planes, enemies, 3) add_middle_planes(middle_planes, enemies, 2) add_big_planes(big_planes, enemies, 1) #增加敌机飞行速度 inc_speed(small_planes, 1) elif level == 2 and your_score > 300000: level = 3 #增加5加小型敌机,3架中型敌机,2加大型敌机 add_small_planes(small_planes, enemies, 5) add_middle_planes(middle_planes, enemies, 3) add_big_planes(big_planes, enemies, 2) #增加敌机飞行速度 inc_speed(small_planes, 1) inc_speed(middle_planes, 1) elif level == 3 and your_score > 600000: level = 4 #增加5加小型敌机,3架中型敌机,2加大型敌机 add_small_planes(small_planes, enemies, 5) add_middle_planes(middle_planes, enemies, 3) add_big_planes(big_planes, enemies, 2) #增加敌机飞行速度 inc_speed(small_planes, 1) inc_speed(middle_planes, 1) inc_speed(big_planes, 1) elif level == 4 and your_score > 1000000: level = 5 #增加5加小型敌机,3架中型敌机,2加大型敌机 add_small_planes(small_planes, enemies, 5) add_middle_planes(middle_planes, enemies, 3) add_big_planes(big_planes, enemies, 2) #增加敌机飞行速度 inc_speed(small_planes, 1) inc_speed(middle_planes, 1) inc_speed(big_planes, 1) #游戏主流程 screen.blit(background, (0, 0))#画背景 if life_num > 0 and not paused: #检测玩家键盘操作控制我方飞机方向 key_pressed = pygame.key.get_pressed() if key_pressed[K_UP]: me.moveUp() if key_pressed[K_DOWN]: me.moveDown() if key_pressed[K_LEFT]: me.moveLeft() if key_pressed[K_RIGHT]: me.moveRight() #若补给包存在则绘制补给包并检测玩家是否获得 if bomb_supply.is_alive: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, me): get_bomb_sound.play() if bomb_num < 3: #全屏炸弹数量上限为3 bomb_num += 1 bomb_supply.is_alive = False if bullet_supply.is_alive: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, me): get_bullet_sound.play() bullet_supply.is_alive = False is_supper_bullet = True pygame.time.set_timer(SUPPER_BULLET_TIME, 18 * 1000) #设定18秒后关闭 #发射子弹 if not is_supper_bullet: if not(delay % 10): bullet1[bullet1_index].reset(me.rect.midtop) bullet1_sound.play() bullet1_index = (bullet1_index + 1) % BULLET1_NUM else: if not(delay % 10): bullet2[bullet2_index].reset(me.rect.midtop) bullet2_sound.play() bullet2_index = (bullet2_index + 1) % BULLET2_NUM #绘制子弹并检测子弹是否击中敌机 for b in (bullet2 if is_supper_bullet else bullet1): if b.is_alive: b.move() screen.blit(b.image, b.rect) enemies_hit = \ pygame.sprite.spritecollide(b, enemies, False, \ pygame.sprite.collide_mask) if enemies_hit: b.is_alive = False for e in enemies_hit: e.energy -= (2 if is_supper_bullet else 1) #普通子弹伤害为1,超级子弹为2 if e.energy <= 0: e.is_alive = False #绘制大型敌机 for each in big_planes: each.move() if each.is_alive: if switch_image:#切换两张图片实现闪烁效果,BOSS特效 screen.blit(each.image1, each.rect) else: screen.blit(each.image2, each.rect) #绘制血槽 pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5), \ (each.rect.right, each.rect.top - 5), \ 2) #血量 > 20%时显示绿色,否则红色 energy_remain = each.energy * 1.0 / enemy.BigPlane.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + each.rect.width * energy_remain, \ each.rect.top - 5), 2) #即将出现在画面中时播放音效 if each.rect.bottom >= -50: bigPlane_out_sound.play(-1)#循环播放确保BOSS飞行中带有音效 else: #毁灭 screen.blit(each.image1, each.rect) if not(delay % 3): if big_plane_destroy == 0: #确保只播放一次音效 bigPlane_down_sound.play() screen.blit(each.destroy_image, each.rect) big_plane_destroy = (big_plane_destroy + 1) % 6 if big_plane_destroy == 0: bigPlane_out_sound.stop()#停止BOSS飞行音效 each.reset() your_score += 10000 #绘制中型敌机 for each in middle_planes: each.move() screen.blit(each.image, each.rect) #绘制血槽 pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5), \ (each.rect.right, each.rect.top - 5), \ 2) #血量 > 20%时显示绿色,否则红色 energy_remain = each.energy * 1.0 / enemy.MiddlePlane.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + each.rect.width * energy_remain, \ each.rect.top - 5), 2) if not each.is_alive:#毁灭 if not(delay % 3): if middle_plane_destroy == 0: middlePlane_down_sound.play() screen.blit(each.destroy_image, each.rect) middle_plane_destroy = (middle_plane_destroy + 1) % 4 if middle_plane_destroy == 0: each.reset() your_score += 5000 #绘制小型敌机 for each in small_planes: each.move() screen.blit(each.image, each.rect) if not each.is_alive:#毁灭 if not(delay % 3): if small_plane_destroy == 0: smallPlane_down_sound.play() screen.blit(each.destroy_image, each.rect) small_plane_destroy = (small_plane_destroy + 1) % 4 if small_plane_destroy == 0: each.reset() your_score += 1000 #检测我方飞机是否被撞 enemies_down = pygame.sprite.spritecollide(me, \ enemies, \ False, \ pygame.sprite.collide_mask) #若我方飞机在非无敌状态被撞,双方飞机都阵亡 if enemies_down and not me.invincible: me.is_alive = False for each in enemies_down: each.is_alive = False #绘制我方飞机 if me.is_alive: if switch_image: screen.blit(me.image1, me.rect) else: screen.blit(me.image2, me.rect) else:#我方飞机毁灭 screen.blit(me.image1, me.rect) if not(delay % 3): if my_plane_destroy == 0: myPlane_down_sound.play() screen.blit(me.destroy_image, me.rect) my_plane_destroy = (my_plane_destroy + 1) % 4 if my_plane_destroy == 0: life_num -= 1 if life_num > 0: me.reset() pygame.time.set_timer(MY_PLANE_INVINCIBLE_TIME, 3000) #3秒后关闭无敌状态 #游戏暂停 elif paused: screen.blit(pause_image, pause_rect) if life_num > 0:#游戏正常运行 #画出分数和难度级别 score_text = font.render(\ 'Score: %s Level: %s' % (str(your_score), str(level)), True, WHITE) screen.blit(score_text, (10, 5)) #绘制状态栏,全屏炸弹图标+数量,生命图标+数量 screen.blit(bomb_image, bomb_rect) bomb_text = font.render(' X %s' % str(bomb_num), True, WHITE) screen.blit(bomb_text, (bomb_rect.left + bomb_rect.width, \ bomb_rect.top + 20)) screen.blit(life_image, life_rect) life_text = font.render(' X %s' % str(life_num), True, WHITE) screen.blit(life_text, (life_rect.left + life_rect.width, \ life_rect.top + 20)) if life_num == 0:#游戏结束 #绘制gameover画面 game_over = game_over_font.render('GAME OVER', True, WHITE) screen.blit(game_over, ((bg_width - game_over.get_width()) // 2, \ (bg_height - game_over.get_height()) // 2)) #关闭其他资源 pygame.mixer.music.stop() pygame.time.set_timer(SUPPLY_TIME, 0) #记录历史最高分 if not recorded:#确保只进行一次文件操作 with open('record.data', 'r') as f: temp = f.read() if temp != '': best_score = int(temp) if best_score < your_score: best_score = your_score with open('record.data', 'w') as f: f.write(str(best_score)) recorded = True pygame.mixer.stop() #停止其他音效 game_over_sound.play() #顺便防止重复播放结束音乐 #防止重复加载图片 background = pygame.image.load('image/gameover_background.jpg').convert() #绘制分数,最高分和当前分数 best_score_text = font.render('Best Score: %s' % str(best_score), True, WHITE) screen.blit(best_score_text, (40, 50)) your_score_text = font.render('Your Score: %s' % str(your_score), True, WHITE) screen.blit(your_score_text, ((bg_width - your_score_text.get_width()) // 2, \ (bg_height + game_over.get_height()) // 2 + 30)) #绘制选择项 screen.blit(quit_text, quit_pos) screen.blit(again_text, again_pos) #鼠标停在Quit上时字体变为红色,否则为白色 #鼠标停在Again上时字体变为绿色,否则为白色 mouse_pos = pygame.mouse.get_pos() #Quit部分 if mouse_pos[0] > quit_pos.left and \ mouse_pos[0] < quit_pos.right and \ mouse_pos[1] > quit_pos.top and \ mouse_pos[1] < quit_pos.bottom: quit_text = font.render('Quit', True, RED) else: quit_text = font.render('Quit', True, WHITE) if mouse_pos[0] > again_pos.left and \ mouse_pos[0] < again_pos.right and \ mouse_pos[1] > again_pos.top and \ mouse_pos[1] < again_pos.bottom: again_text = font.render('Again', True, GREEN) else: again_text = font.render('Again', True, WHITE) #每隔5帧切换图片 if not(delay % 5): switch_image = not switch_image delay -= 1 if not delay: delay = 100 #显示游戏画面 pygame.display.flip() #设置帧率 clock.tick(60)
def main(): # Keep playing the background music pygame.mixer.music.play(-1) # Generate player's plane object player = myplane.MyPlane(bg_size) # Generate enemy groups and add enemies enemies = pygame.sprite.Group() small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, INITIAL_SMALL_ENEMIES_NUM) medium_enemies = pygame.sprite.Group() add_medium_enemies(medium_enemies, enemies, INITIAL_MEDIUM_ENEMIES_NUM) large_enemies = pygame.sprite.Group() add_large_enemies(large_enemies, enemies, INITIAL_LARGE_ENEMIES_NUM) # Score system score = 0 score_font = pygame.font.Font(GAME_FONT_SRC, MEDIUM_FONT_SIZE) level = 1 # Life system life_num = INITIAL_LIFE_NUM life_image = pygame.image.load(LIFE_IMAGE_SRC).convert_alpha() life_rect = life_image.get_rect() # Bomb bomb_num = INITIAL_BOMB_NUM bomb_image = pygame.image.load(BOMB_IMAGE_SRC).convert_alpha() bomb_rect = bomb_image.get_rect() bomb_font = pygame.font.Font(GAME_FONT_SRC, LARGE_FONT_SIZE) # Bomb supply bomb_supply = supply.BombSupply(bg_size) # Bullet supply bullet_supply = supply.BulletSupply(bg_size) # Double bullet flag is_double_bullet = False # Supply timer event SUPPLY_TIME = USEREVENT pygame.time.set_timer(SUPPLY_TIME, SUPPLY_TIME_DURATION) # 15 seconds = 15 * 1000 milliseconds DOUBLE_BULLET_TIME = USEREVENT + 1 INVINCIBLE_TIME = USEREVENT + 2 # Pause paused = False pause_nor_image = pygame.image.load(PAUSE_NOR_IMAGE_SRC).convert_alpha() pause_pressed_image = pygame.image.load(PAUSE_PRESSED_IMAGE_SRC).convert_alpha() resume_nor_image = pygame.image.load(RESUME_NOR_IMAGE_SRC).convert_alpha() resume_pressed_image = pygame.image.load(RESUME_PRESSED_IMAGE_SRC).convert_alpha() paused_rect = pause_nor_image.get_rect() paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10 paused_image = pause_nor_image # Gameover image gameover_font = pygame.font.Font(GAME_FONT_SRC, LARGE_FONT_SIZE) gameover_image = pygame.image.load(GAMEOVER_IMAGE_SRC).convert_alpha() gameover_rect = gameover_image.get_rect() restart_image = pygame.image.load(RESTART_IMAGE_SRC).convert_alpha() restart_rect = restart_image.get_rect() # Generate bullets bullet1_list = [] bullet1_index = 0 bullet1_num = 4 for i in range(bullet1_num): bullet1_list.append(bullet.Bullet1(player.rect.midtop)) bullet2_list = [] bullet2_index = 0 bullet2_num = 8 for i in range(bullet2_num // 2): bullet2_list.append(bullet.Bullet2((player.rect.centerx - 33, player.rect.centery))) bullet2_list.append(bullet.Bullet2((player.rect.centerx + 30, player.rect.centery))) # Set game's clock clock = pygame.time.Clock() # Set player's image switch flag switch_image = False # Set score record flag recorded = False # Set an initial time counter delay = 60 # Set planes' destroy index player_destroy_index = 0 se_destroy_index = 0 me_destroy_index = 0 le_destroy_index = 0 running = True while running: # Detect operations for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type == MOUSEMOTION: if paused_rect.collidepoint(event.pos): if paused: paused_image = resume_pressed_image else: paused_image = pause_pressed_image else: if paused: paused_image = resume_nor_image else: paused_image = pause_nor_image if event.type == MOUSEBUTTONDOWN: if event.button == 1 and paused_rect.collidepoint(event.pos): paused = not paused if paused: pygame.time.set_timer(SUPPLY_TIME, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: pygame.time.set_timer(SUPPLY_TIME, SUPPLY_TIME_DURATION) pygame.mixer.music.unpause() pygame.mixer.unpause() if event.type == KEYDOWN: if event.key == K_SPACE: if bomb_num > 0: bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0: each.active = False if event.type == SUPPLY_TIME: supply_sound.play() if choice([True, False]): bomb_supply.reset() else: bullet_supply.reset() if event.type == DOUBLE_BULLET_TIME: is_double_bullet = False pygame.time.set_timer(DOUBLE_BULLET_TIME, 0) if event.type == INVINCIBLE_TIME: player.invincible = False pygame.time.set_timer(INVINCIBLE_TIME, 0) # Draw the background image to the game window screen.blit(background, (0, 0)) # Draw the pause image if life_num > 0: # display pause button screen.blit(paused_image, paused_rect) # display score score_text = score_font.render(f"Score: {score}", True, WHITE) screen.blit(score_text, SCORE_TEXT_POSITION) # level upgrade if level == 1 and score > L2_SCORE_THRESHOLD: level = 2 upgrade_sound.play() add_small_enemies(small_enemies, enemies, L2_SMALL_ENEMIES_INCRE) add_medium_enemies(medium_enemies, enemies, L2_MEDIUM_ENEMIES_INCRE) add_large_enemies(large_enemies, enemies, L2_LARGE_ENEMIES_INCRE) speed_up(small_enemies, L2_SMALL_SPEED_INCRE) elif level == 2 and score > L3_SCORE_THRESHOLD: level = 3 upgrade_sound.play() add_small_enemies(small_enemies, enemies, L3_SMALL_ENEMIES_INCRE) add_medium_enemies(medium_enemies, enemies, L3_MEDIUM_ENEMIES_INCRE) add_large_enemies(large_enemies, enemies, L3_LARGE_ENEMIES_INCRE) speed_up(small_enemies, L3_SMALL_SPEED_INCRE) speed_up(medium_enemies, L3_MEDIUM_SPEED_INCRE) elif level == 3 and score > L4_SCORE_THRESHOLD: level = 4 upgrade_sound.play() add_small_enemies(small_enemies, enemies, L4_SMALL_ENEMIES_INCRE) add_medium_enemies(medium_enemies, enemies, L4_MEDIUM_ENEMIES_INCRE) add_large_enemies(large_enemies, enemies, L4_LARGE_ENEMIES_INCRE) speed_up(small_enemies, L4_SMALL_SPEED_INCRE) speed_up(medium_enemies, L4_MEDIUM_SPEED_INCRE) elif level == 4 and score > L5_SCORE_THRESHOLD: level = 5 upgrade_sound.play() add_small_enemies(small_enemies, enemies, L5_SMALL_ENEMIES_INCRE) add_medium_enemies(medium_enemies, enemies, L5_MEDIUM_ENEMIES_INCRE) add_large_enemies(large_enemies, enemies, L5_LARGE_ENEMIES_INCRE) speed_up(small_enemies, L5_SMALL_SPEED_INCRE) speed_up(medium_enemies, L5_MEDIUM_SPEED_INCRE) speed_up(large_enemies, L5_LARGE_SPEED_INCRE) if life_num > 0 and (not paused): # Detect keyboard operations key_pressed = pygame.key.get_pressed() if key_pressed[K_UP] or key_pressed[K_w]: player.move_up() if key_pressed[K_DOWN] or key_pressed[K_s]: player.move_down() if key_pressed[K_LEFT] or key_pressed[K_a]: player.move_left() if key_pressed[K_RIGHT] or key_pressed[K_d]: player.move_right() # display lives image for i in range(life_num): screen.blit(life_image, \ (width - 10 - (i + 1) * life_rect.width, \ height - 10 - life_rect.height)) # display bomb bomb_text = bomb_font.render("× %d" % bomb_num, True, WHITE) bomb_text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - bomb_text_rect.height)) # release bomb supply package if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, player): if bomb_num < INITIAL_BOMB_NUM: bomb_num += 1 get_bomb_sound.play() bomb_supply.active = False # release bullet supply package if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, player): get_bullet_sound.play() pygame.time.set_timer(DOUBLE_BULLET_TIME, DOUBLE_BULLET_TIME_DURATION) is_double_bullet = True bullet_supply.active = False # every 10 times of refresh, fire a bullet if not (delay % 10): bullet_sound.play() if is_double_bullet: bullets = bullet2_list bullets[bullet2_index].reset((player.rect.centerx - 33, player.rect.centery)) bullets[bullet2_index + 1].reset((player.rect.centerx + 30, player.rect.centery)) bullet2_index = (bullet2_index + 2) % bullet2_num else: bullets = bullet1_list bullets[bullet1_index].reset(player.rect.midtop) bullet1_index = (bullet1_index + 1) % bullet1_num # Check hitting an enemy for b in bullets: if b.active: b.move() screen.blit(b.image, b.rect) enemies_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask) if enemies_hit: b.active = False for e in enemies_hit: if e in large_enemies or e in medium_enemies or e in small_enemies: e.energy -= 1 e.hit = True if e.energy == 0: e.active = False else: e.active = False # Small enemies behavior for each in small_enemies: if each.active: each.move() if each.hit: each.hit = False screen.blit(each.image, each.rect) # Energy bar pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5), \ (each.rect.right, each.rect.top - 5), \ 2) energy_remain = each.energy / enemy.SmallEnemy.energy if energy_remain > 0.5: energy_color = GREEN else: energy_color = RED # Re-draw the energy bar pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), \ 2) else: if not delay % 3: screen.blit(each.destroy_images[se_destroy_index], each.rect) se_destroy_index = (se_destroy_index + 1) % 4 if se_destroy_index == 0: enemy1_down_sound.play() score += SMALL_ENEMY_SCORE each.reset() # Medium enemies behavior for each in medium_enemies: if each.active: each.move() if each.hit: screen.blit(each.image_hit, each.rect) each.hit = False else: screen.blit(each.image, each.rect) # Energy bar pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5), \ (each.rect.right, each.rect.top - 5), \ 2) energy_remain = each.energy / enemy.MediumEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED # Re-draw the energy bar pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), \ 2) else: if not delay % 3: screen.blit(each.destroy_images[me_destroy_index], each.rect) me_destroy_index = (me_destroy_index + 1) % 4 if me_destroy_index == 0: enemy2_down_sound.play() score += MEDIUM_ENEMY_SCORE each.reset() # Large enemies behavior for each in large_enemies: if each.active: each.move() if each.hit: screen.blit(each.image_hit, each.rect) each.hit = False else: if switch_image: screen.blit(each.image1, each.rect) else: screen.blit(each.image2, each.rect) pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5), \ (each.rect.right, each.rect.top - 5), 2) energy_remain = each.energy / enemy.LargeEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), \ 2) else: if not delay % 3: screen.blit(each.destroy_images[le_destroy_index], each.rect) le_destroy_index = (le_destroy_index + 1) % 6 if le_destroy_index == 0: enemy3_down_sound.play() score += LARGE_ENEMY_SCORE each.reset() # Play behavior if player.active: # switch player's image if switch_image: screen.blit(player.image1, player.rect) else: screen.blit(player.image2, player.rect) else: # load destroy images if not delay % 3: screen.blit(player.destroy_images[player_destroy_index], player.rect) player_destroy_index = (player_destroy_index + 1) % 4 if player_destroy_index == 0: player_down_sound.play() life_num -= 1 player.reset() pygame.time.set_timer(INVINCIBLE_TIME, INVINCIBLE_TIME_DURATION) # Detect collision (player vs. enemies) enemies_down = pygame.sprite.spritecollide(player, enemies, False, pygame.sprite.collide_mask) if enemies_down and not player.invincible: player.active = False for e in enemies_down: e.active = False elif life_num == 0: pygame.mixer.music.stop() pygame.mixer.stop() pygame.time.set_timer(SUPPLY_TIME, 0) if not recorded: recorded = True with open(RECORD_SCORE_FILE_NAME, "r") as f: record_score = int(f.read()) if score > record_score: with open(RECORD_SCORE_FILE_NAME, "w") as f: f.write(str(score)) record_score_text = score_font.render(f"Best score: {record_score}", True, WHITE) screen.blit(record_score_text, RECORD_SCORE_TEXT_POSITION) gameover_score_text = gameover_font.render("Your Score", True, WHITE) gameover_score_text_rect = gameover_score_text.get_rect() gameover_score_text_rect.left = (width - gameover_score_text_rect.width) // 2 gameover_score_text_rect.top = height // 3 screen.blit(gameover_score_text, gameover_score_text_rect) gameover_score_text2 = gameover_font.render(str(score), True, WHITE) gameover_score_text2_rect = gameover_score_text2.get_rect() gameover_score_text2_rect.left = (width - gameover_score_text2_rect.width) // 2 gameover_score_text2_rect.top = gameover_score_text_rect.bottom + 10 screen.blit(gameover_score_text2, gameover_score_text2_rect) restart_rect.left = (width - restart_rect.width) // 2 restart_rect.top = height - 200 screen.blit(restart_image, restart_rect) gameover_rect.left = (width - restart_rect.width) // 2 gameover_rect.top = restart_rect.bottom + 10 screen.blit(gameover_image, gameover_rect) if pygame.mouse.get_pressed()[0]: pos = pygame.mouse.get_pos() if restart_rect.left < pos[0] < restart_rect.right and restart_rect.top < pos[1] < restart_rect.bottom: main() elif gameover_rect.left < pos[0] < gameover_rect.right and gameover_rect.top < pos[1] < gameover_rect.bottom: pygame.quit() sys.exit() # every 6 times of refresh, switch the player's image if not delay % 6: switch_image = not switch_image # every refresh reduce time counter by 1 # once the time counter is 0, reset it back to 60 if delay == 0: delay = 60 delay -= 1 pygame.display.flip() # refresh 60 times per second clock.tick(60)
def main(): is_double_bullet = False pygame.mixer_music.play(-1) # create myPlane my_plane = myPlane.MyPlane(bg_size) # create enemy plane enemies = pygame.sprite.Group() # 小型敌方飞机 smallEnemies = pygame.sprite.Group() addSmallEnemies(smallEnemies, enemies, data.BigEnemiesNum) # 中型敌方飞机 midEnemies = pygame.sprite.Group() addMidEnemies(midEnemies, enemies, data.MidEnemiesNum) # 大型敌方飞机 bigEnemies = pygame.sprite.Group() addBigEnemies(bigEnemies, enemies, data.BigEnemiesNum) bullets = [] # 我方子弹 普通 if True: bullet1 = [] bullet1_index = 0 bullet1_num = data.SingleBullet for i in range(bullet1_num): bullet1.append(bullet.Bullet1(my_plane.rect.midtop)) # 我方子弹 二重 if True: bullet2 = [] bullet2_index = 0 bullet2_num = data.DoubleBullet for i in range(bullet2_num // 2): bullet2.append( bullet.Bullet2( (my_plane.rect.centerx - 33, my_plane.rect.centery))) bullet2.append( bullet.Bullet2( (my_plane.rect.centerx + 30, my_plane.rect.centery))) # 二重子弹 定时器 DOUBLE_BULLET_TIME = USEREVENT + 1 # 飞机破坏图片索引 if True: e1_destroy_index = 0 e2_destroy_index = 0 e3_destroy_index = 0 me_destroy_index = 0 # 统计得分 score = 0 score_font = pygame.font.Font("font/font.ttf", 36) # 暂停游戏 if True: paused = False pause_nor_image = pygame.image.load( "./images/pause_nor.png").convert_alpha() pause_pressed_image = pygame.image.load( "./images/pause_pressed.png").convert_alpha() resume_nor_image = pygame.image.load( "./images/resume_nor.png").convert_alpha() resume_pressed_image = pygame.image.load( "./images/resume_pressed.png").convert_alpha() pause_rect = pause_nor_image.get_rect() pause_rect.left, pause_rect.top = width - pause_rect.width - 10, 10 pause_image = pause_nor_image # 游戏难度 level = data.GameLevel # 全屏炸弹 if True: bomb_image = pygame.image.load("./images/bomb.png").convert_alpha() bomb_rect = bomb_image.get_rect() bomb_font = pygame.font.Font("font/font.ttf", 48) bomb_num = data.BombNum # 每20s触发一次补给 if True: bullet_supply = supply.BulletSupply(bg_size) bomb_supply = supply.BombSupply(bg_size) SUPPLY_TIME = USEREVENT pygame.time.set_timer(SUPPLY_TIME, data.SupplyIntervelTime) clock = pygame.time.Clock() # 切换我放飞机 switch_iamge = True # 生命数量 if True: life_image = pygame.image.load("./images/life.png").convert_alpha() life_rect = life_image.get_rect() life_num = data.Life # 解除我方复活后的短暂无敌 计时器 invincible_time = USEREVENT + 2 # 绘制结束界面 if True: gameover_font = pygame.font.Font("font/font.ttf", 48) again_image = pygame.image.load("./images/again.png").convert_alpha() again_rect = again_image.get_rect() gameover_image = pygame.image.load( "./images/gameover.png").convert_alpha() gameover_rect = gameover_image.get_rect() # 用于阻止重复开关存档文件 save saved = False # 用于延迟 delay = 100 running = True while running: # 所有事件event for event in pygame.event.get(): if event.type == QUIT: pygame, exit() sys.exit() elif event.type == MOUSEBUTTONDOWN: if event.button == 1 and pause_rect.collidepoint(event.pos): paused = not paused if paused: pause_image = resume_pressed_image pygame.time.set_timer(SUPPLY_TIME, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: pause_image = pause_pressed_image pygame.time.set_timer(SUPPLY_TIME, data.SupplyIntervelTime) pygame.mixer.music.unpause() pygame.mixer.unpause() # elif event.type ==MOUSEMOTION: # if pause_rect.collidepoint(event.pos): # if paused: # pause_image = resume_pressed_image # else: # pause_image = pause_pressed_image # else: # if paused: # pause_image = resume_nor_image # else: # pause_image = pause_nor_image elif event.type == KEYDOWN: if event.key == K_SPACE: print("按之前还有%d个" % bomb_num) if bomb_num: bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0: each.alive = False elif event.type == SUPPLY_TIME: supply_sound.play() if random.randint(1, 4) % 4 == 0: bomb_supply.reset() else: bullet_supply.reset() elif event.type == DOUBLE_BULLET_TIME: is_double_bullet = False pygame.time.set_timer(DOUBLE_BULLET_TIME, 0) elif event.type == invincible_time: my_plane.invincible = False pygame.time.set_timer(invincible_time, 0) # 根据用户的得分来增加难度 if score >= 5000 * (level**2): level += 1 upgrade_sound.play() addSmallEnemies(smallEnemies, enemies, 5) addMidEnemies(midEnemies, enemies, 3) addBigEnemies(bigEnemies, enemies, 1) inc_speed(smallEnemies, 1) inc_speed(midEnemies, 0.5) # inc_speed(bigEnemies, 0.1) print("现在的等级是%d级" % level) screen.blit(background, (0, 0)) # 游戏进行时相关 !important # 游戏进行时相关 !important # 游戏进行时相关 !important if life_num and not paused: # check keyboard event key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: my_plane.moveUp() if key_pressed[K_s] or key_pressed[K_DOWN]: my_plane.moveDown() if key_pressed[K_a] or key_pressed[K_LEFT]: my_plane.moveLeft() if key_pressed[K_d] or key_pressed[K_RIGHT]: my_plane.moveRight() # 绘制大型敌机 for each in bigEnemies: if each.alive: each.move() if each.hit: screen.blit(each.image_hit, each.rect) each.hit = False else: if switch_iamge: screen.blit(each.image1, each.rect) else: screen.blit(each.image2, each.rect) # 绘制血槽 pygame.draw.line(screen, BLACK, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) # 生命大于20%时显示绿色,以下则为红色 energy_remain = each.energy / enemy.BigEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line( screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) # 即将出现时,播ngm if each.rect.bottom == -50: enemy3_fly_sound.play(-1) # -1循环播放 else: # 飞机被破坏 if not (delay % 5): if e3_destroy_index == 0: enemy3_down_sound.play() screen.blit(each.destroy_images[e3_destroy_index], each.rect) e3_destroy_index = (e3_destroy_index + 1) % 6 if e3_destroy_index == 0: enemy3_fly_sound.stop() score += 5000 each.reset() # 绘制中型敌机 for each in midEnemies: if each.alive: each.move() if each.hit: screen.blit(each.image_hit, each.rect) each.hit = False else: screen.blit(each.image, each.rect) # 绘制血槽 pygame.draw.line(screen, BLACK, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) # 生命大于20%时显示绿色,以下则为红色 energy_remain = each.energy / enemy.MidEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line( screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) else: # 飞机被破坏 if not (delay % 5): if e2_destroy_index == 0: enemy2_down_sound.play() screen.blit(each.destroy_images[e2_destroy_index], each.rect) e2_destroy_index = (e2_destroy_index + 1) % 4 if e2_destroy_index == 0: score += 1000 each.reset() # 绘制小型敌机 for each in smallEnemies: if each.alive: each.move() screen.blit(each.image, each.rect) else: # 飞机被破坏 if not (delay % 5): if e1_destroy_index == 0: enemy1_down_sound.play() screen.blit(each.destroy_images[e1_destroy_index], each.rect) e1_destroy_index = (e1_destroy_index + 1) % 4 if e1_destroy_index == 0: score += 100 each.reset() # 绘制我放飞机 if my_plane.alive: if switch_iamge: screen.blit(my_plane.image1, my_plane.rect) # print(my_plane.rect) # switch_iamge = False else: screen.blit(my_plane.image2, my_plane.rect) # switch_iamge = True else: # 我方飞机被破坏 if not (delay % 3): if me_destroy_index == 0: me_down_sound.play() screen.blit(my_plane.destroy_images[me_destroy_index], my_plane.rect) e1_destroy_index = (e1_destroy_index + 1) % 4 if e1_destroy_index == 0: life_num -= 1 # 重生 my_plane.reset() pygame.time.set_timer(invincible_time, 3 * 1000) # 检测我方飞机是否被撞 enemies_down = pygame.sprite.spritecollide( my_plane, enemies, False, pygame.sprite.collide_mask) if enemies_down and not my_plane.invincible: # 这面这个控制我方无敌 my_plane.alive = False for e in enemies_down: e.alive = False # 发射我方子弹 if not (delay % 10): bullet_sound.play() if is_double_bullet: bullets = bullet2 bullets[bullet2_index].reset( (my_plane.rect.centerx - 33, my_plane.rect.centery)) bullets[bullet2_index + 1].reset( (my_plane.rect.centerx + 30, my_plane.rect.centery)) bullet2_index = (bullet2_index + 2) % bullet2_num else: bullets = bullet1 bullets[bullet1_index].reset(my_plane.rect.midtop) bullet1_index = (bullet1_index + 1) % bullet1_num # 检测子弹是否击中敌机 for b in bullets: if b.alive: b.move() screen.blit(b.image, b.rect) enemy_hit = pygame.sprite.spritecollide( b, enemies, False, pygame.sprite.collide_mask) if enemy_hit: bullet.alive = False for e in enemy_hit: # 下面用来判断大中小敌机的不同情况 if e in midEnemies or e in bigEnemies: e.hit = True e.energy -= 1 if e.energy == 0: e.alive = False else: e.alive = False # 绘制补给炸弹并判断是否获得 if bomb_supply.alive: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, my_plane): get_bomb_sound.play() bomb_num += 1 bomb_supply.alive = False # 绘制超级子弹并判断是否获得 if bullet_supply.alive: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, my_plane): get_bullet_sound.play() # 发射二重子弹 is_double_bullet = True pygame.time.set_timer(DOUBLE_BULLET_TIME, data.DoubleBulletTime) bullet_supply.alive = False # 绘制剩余生命life数量 if True: if life_num: for i in range(life_num): screen.blit(life_image, (width - 10 - (i + 1) * life_rect.width, height - 10 - life_rect.height)) # 绘制剩余炸弹 if True: bomb_text = bomb_font.render("× %d" % bomb_num, True, WHITE) text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit( bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height)) # 绘制分数栏 score_text = score_font.render( "LV:%d Score : %s " % (level, str(score)), True, WHITE) screen.blit(score_text, (10, 5)) # 绘制暂停按钮 screen.blit(pause_image, pause_rect) elif life_num: # 绘制分数栏 score_text = score_font.render( "LV:%d Score : %s " % (level, str(score)), True, WHITE) screen.blit(score_text, (10, 5)) # 绘制暂停按钮 screen.blit(pause_image, pause_rect) # 绘制游戏结束画面 elif life_num == 0: # 背景音乐停止 pygame.mixer.music.stop() # 停止全部音效 pygame.mixer.stop() # 停止补给发放 pygame.time.set_timer(SUPPLY_TIME, 0) # 存档相关 if not saved: # 读取历史最高分 with open("save.txt", "r") as f: record_score = int(f.read()) # 如果高于最高分,则存档 if score > record_score: with open("save.txt", "w") as f: f.write(str(score)) # 结束界面 if True: record_score_text = score_font.render( "Best : %d" % record_score, True, WHITE) screen.blit(record_score_text, (50, 50)) gameover_text1 = gameover_font.render("Your Score: ", True, WHITE) gameover_text1_rect = gameover_text1.get_rect() gameover_text1_rect.left, gameover_text1_rect.top = \ (width - gameover_text1_rect.width) // 2, height // 2 screen.blit(gameover_text1, gameover_text1_rect) gameover_text2 = gameover_font.render(str(score), True, WHITE) gameover_text2_rect = gameover_text2.get_rect() gameover_text2_rect.left, gameover_text2_rect.top = \ (width - gameover_text2_rect.width) // 2, \ gameover_text1_rect.bottom + 10 screen.blit(gameover_text2, gameover_text2_rect) again_rect.left, again_rect.top = \ (width - again_rect.width) // 2, \ gameover_text2_rect.bottom + 50 screen.blit(again_image, again_rect) gameover_rect.left, gameover_rect.top = \ (width - again_rect.width) // 2, \ again_rect.bottom + 10 screen.blit(gameover_image, gameover_rect) score_text = score_font.render("Score : %s " % str(score), True, WHITE) screen.blit(score_text, (10, 5)) # 检测用户的鼠标操作 # 如果用户按下鼠标左键 if pygame.mouse.get_pressed()[0]: pos = pygame.mouse.get_pos() if again_rect.left < pos[0] < again_rect.right and \ again_rect.top < pos[1] < again_rect.bottom: main() elif gameover_rect.left < pos[0] < gameover_rect.right and \ gameover_rect.top < pos[1] < gameover_rect.bottom: pygame.quit() sys.exit() # mark是否使用超级子弹 # 切换照片 if True: if not (delay % 5): switch_iamge = not switch_iamge delay -= 1 if not delay: delay = 100 pygame.display.flip() clock.tick(60)
def main(): # If the loops is -1 then the music will repeat indefinitely. pygame.mixer.music.play(-1) # create an object to help track time. # The clock also provides several functions to help control a game's framerate. clock = pygame.time.Clock() # 生成我方飞机 me = myplane.Myplane(bg_size) # 生成敌机 enemies = pygame.sprite.Group() # 生成敌方小飞机 small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, 5) # 生成敌方中飞机 mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, 25) # 生成敌方大飞机 big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 3) # 生成普通子弹 bullet1 = [] bullet1_index = 0 BULLET_NUM1 = 5 for i in range(BULLET_NUM1): bullet1.append(bullet.Bullet1(me.rect.midtop)) # 生成超级子弹 bullet2 = [] bullet2_index = 0 BULLET_NUM2 = 16 for i in range(BULLET_NUM2//2): bullet2.append(bullet.Bullet2((me.rect.centerx-33, me.rect.centery))) bullet2.append(bullet.Bullet2((me.rect.centerx+30, me.rect.centery))) # 得分 score = 0 score_font = pygame.font.Font("./font/font.ttf",36) # 难度等级 level = 1 # 定义全屏炸弹 bomb_image = pygame.image.load("./images/bomb.png").convert_alpha() bomb_rect = bomb_image.get_rect() bomb_font = pygame.font.Font("./font/font.ttf", 48) bomb_num = 3 # 每30s发放一个补给包 bullet_supply = supply.BulletSupply(bg_size) bomb_supply = supply.BombSupply(bg_size) SUPPLY_TIME = USEREVENT pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) # 游戏结束画面 gameover_font = pygame.font.Font("font/font.ttf", 48) again_image = pygame.image.load("images/again.png").convert_alpha() again_rect = again_image.get_rect() gameover_image = pygame.image.load("images/gameover.png").convert_alpha() gameover_rect = gameover_image.get_rect() # 超级子弹定时器 DOUBBLE_BULLET_TIME = USEREVENT + 1 # 无敌时间计时器 INVINCIBLE_TIME = USEREVENT + 2 # 标志是否使用超级子弹 is_doubble_bullet = False # 生命数量 life_image = pygame.image.load("./images/life.png").convert_alpha() life_rect = life_image.get_rect() life_num = 3 # 暂停设置 paused = False pause_nor_image = pygame.image.load("./images/pause_nor.png").convert_alpha() pause_pressed_image = pygame.image.load("./images/pause_pressed.png").convert_alpha() resume_nor_image = pygame.image.load("./images/resume_nor.png").convert_alpha() resume_pressed_image = pygame.image.load("./images/resume_pressed.png").convert_alpha() pause_rect = pause_nor_image.get_rect() pause_rect.left, pause_rect.top = width - pause_rect.width - 10, 10 pause_image = pause_nor_image # 飞机爆炸索引 e1_destroy_index = 0 e2_destroy_index = 0 e3_destroy_index = 0 me_destroy_index = 0 # 用于切换图片 switch_image = True # 用于延迟 delay = 100 running = True # 用于限制重复打开存取记录 recorded = False while running: # get events from the queue for event in pygame.event.get(): # 游戏退出事件 if event.type == QUIT: pygame.quit() sys.exit() # 鼠标点击事件 elif event.type == MOUSEBUTTONDOWN: if event.button == 1 and pause_rect.collidepoint(event.pos): paused = not paused if paused: pygame.time.set_timer(SUPPLY_TIME, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) pygame.mixer.music.unpause() pygame.mixer.unpause() # 鼠标移动事件(悬停) elif event.type == MOUSEMOTION: if pause_rect.collidepoint(event.pos): if paused: pause_image = resume_pressed_image else: pause_image = pause_pressed_image else: if paused: pause_image = resume_nor_image else: pause_image = pause_nor_image # 空格点击事件 elif event.type == KEYDOWN: if event.key == K_SPACE: if bomb_num: bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0: each.active = False elif event.type == SUPPLY_TIME: supply_sound.play() if random.choice([True, False]): bullet_supply.reset() else: bomb_supply.reset() elif event.type == DOUBBLE_BULLET_TIME: is_doubble_bullet = False pygame.time.set_timer(DOUBBLE_BULLET_TIME, 0) elif event.type == INVINCIBLE_TIME: me.invincible = False # 结束无敌时间计时器 pygame.time.set_timer(INVINCIBLE_TIME, 0) # 根据用户的得分增加难度 if level == 1 and score > 50000: level = 2 upgrade_sound.play() # 增加3架小型敌机、2架中型敌机和1架大型敌机 add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) # 提升小型敌机速度 inc_speed(small_enemies, 1) elif level == 2 and score > 300000: level = 3 upgrade_sound.play() # 增加5架小型敌机、3架中型敌机和2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # 提升小型敌机速度 inc_speed(small_enemies, 1) # 提升中型敌机速度 inc_speed(mid_enemies, 1) elif level == 3 and score > 600000: level = 4 upgrade_sound.play() # 增加5架小型敌机、3架中型敌机和2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # 提升小型敌机速度 inc_speed(small_enemies, 1) # 提升中型敌机速度 inc_speed(mid_enemies, 1) elif level == 4 and score > 1000000: level = 5 upgrade_sound.play() # 增加5架小型敌机、3架中型敌机和2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # 提升小型敌机速度 inc_speed(small_enemies, 1) # 提升中型敌机速度 inc_speed(mid_enemies, 1) # 绘制背景图片 # blit: draw one image onto another # surface.blit(source, dest, area=None, special_flags=0) -> Rect screen.blit(background, (0, 0)) if life_num > 0 and not paused: # 检测用户的键盘操作 key_press = pygame.key.get_pressed() if key_press[K_w] or key_press[K_UP]: me.moveUp() if key_press[K_s] or key_press[K_DOWN]: me.moveDown() if key_press[K_a] or key_press[K_LEFT]: me.moveLeft() if key_press[K_d] or key_press[K_RIGHT]: me.moveRight() # 检测全屏炸弹补给并检测是否获得 if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, me): get_bomb_sound.play() if bomb_num < 3: bomb_num += 1 bomb_supply.active = False # 检测超级子弹补给并检测是否获得 if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, me): get_bullet_sound.play() is_doubble_bullet = True pygame.time.set_timer(DOUBBLE_BULLET_TIME, 18 * 1000) bullet_supply.active = False # 每十帧发射一颗子弹 if not(delay % 10): bullet_sound.play() if is_doubble_bullet: bullets = bullet2 bullets[bullet2_index].reset((me.rect.centerx-33, me.rect.centery)) bullets[bullet2_index+1].reset((me.rect.centerx+30, me.rect.centery)) bullet2_index = (bullet2_index + 2) % BULLET_NUM2 else: bullets = bullet1 bullets[bullet1_index].reset(me.rect.midtop) bullet1_index = (bullet1_index + 1) % BULLET_NUM1 # 检测子弹是否击中敌机 for b in bullets: if b.active: # 绘制子弹 b.move() screen.blit(b.image, b.rect) # enemy_hit中存放由pygame.sprite.spritecollide返回的敌机对象 enemy_hit = pygame.sprite.spritecollide(b,enemies, False, pygame.sprite.collide_mask) if enemy_hit: b.active = False for e in enemy_hit: if e in big_enemies or e in mid_enemies: e.hit = True e.energy -= 1 if e.energy == 0: e.active = False else: e.active = False # 绘制大型敌机(是大型敌机在最里面,小飞机在最外面) for each in big_enemies: if each.active: each.move() if each.hit: screen.blit(each.hit_image, each.rect) each.hit = False else: if switch_image: screen.blit(each.image1, each.rect) else: screen.blit(each.image2, each.rect) # 绘制血槽 # 绘制底槽 pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top -5), \ (each.rect.right, each.rect.top - 5), \ 2) # 当生命值大于20%时显示绿色,否则显示红色 energy_remain = each.energy / enemy.BigEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED # 绘制血量 pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + energy_remain * each.rect.width, each.rect.top - 5), \ 2) # 即将出现在画面中,播放音效 if each.rect.bottom == -50: enemy3_fly_sound.play(-1) else: # 毁灭 if not (delay % 3): if e3_destroy_index == 0: enemy3_down_sound.play() screen.blit(each.destroy_image[e3_destroy_index], each.rect) e3_destroy_index = (e3_destroy_index+1) % 6 if e3_destroy_index == 0: enemy3_fly_sound.stop() score += 10000 each.reset() # 绘制中型敌机 for each in mid_enemies: if each.active: each.move() if each.hit: screen.blit(each.hit_image, each.rect) each.hit = False else: screen.blit(each.image, each.rect) # 绘制血槽 # 绘制底槽 pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5), \ (each.rect.right, each.rect.top - 5), \ 2) # 当生命值大于20%时显示绿色,否则显示红色 energy_remain = each.energy / enemy.MidEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED # 绘制血量 pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + energy_remain * each.rect.width, each.rect.top - 5), \ 2) else: # 毁灭 if not(delay % 3): if e2_destroy_index == 0: enemy2_down_sound.play() screen.blit(each.destroy_image[e2_destroy_index], each.rect) e2_destroy_index = (e2_destroy_index+1) % 4 if e2_destroy_index == 0: score += 6000 each.reset() # 绘制小型敌机 for each in small_enemies: if each.active: each.move() screen.blit(each.image, each.rect) else: # 毁灭 if not (delay % 3): if e1_destroy_index == 0: enemy1_down_sound.play() screen.blit(each.destroy_image[e1_destroy_index], each.rect) e1_destroy_index = (e1_destroy_index + 1) % 4 if e1_destroy_index == 0: score += 1000 each.reset() # 检测我方飞机是否碰撞 enemy_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask) if enemy_down and not me.invincible: me.active = False for e in enemy_down: e.active = False # 绘制我方飞机(动态效果) if me.active: if switch_image: screen.blit(me.image1, me.rect) else: screen.blit(me.image2, me.rect) else: # 毁灭 if not(delay % 3): if me_destroy_index == 0: me_down_sound.play() screen.blit(me.destroy_image[me_destroy_index], me.rect) me_destroy_index = (me_destroy_index+1) % 4 if me_destroy_index == 0: life_num -= 1 me.reset() # 调用无敌时间计时器 pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000) # 绘制全屏炸弹数量 bomb_text = bomb_font.render("x %d" % bomb_num, True, WHITE) text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - bomb_rect.height)) # 绘制生命数量 if life_num > 0: for i in range(life_num): screen.blit(life_image,\ (width - 10 - (i+1) * life_rect.width, \ height - 10 - life_rect.height)) # 绘制分数 score_text = score_font.render("Score : %s" % str(score), True, WHITE) screen.blit(score_text, (10, 5)) # 绘制游戏结束画面 elif life_num == 0: # 背景音乐停止 pygame.mixer.music.stop() # 停止音效 pygame.mixer.stop() # 停止发放补给 pygame.time.set_timer(SUPPLY_TIME, 0) if not recorded: recorded = True # 读取历史最高得分 with open("D:\\Desktop\\python\\python_basics\\100day\\train_project\\pygame\\record.txt", "r") as f: record_score = int(f.read()) # 如果玩家分数高于历史最高峰,则存档 if score > record_score: with open("D:\\Desktop\\python\\python_basics\\100day\\train_project\\pygame\\record.txt", "w") as f: f.write(str(score)) # 绘制结束画面 record_score_text = score_font.render("Best: %d" % record_score, True, WHITE) screen.blit(record_score_text, (50, 50)) gameover_text1 = gameover_font.render("Your Score: ", True, WHITE) gameover_text1_rect = gameover_text1.get_rect() gameover_text1_rect.left, gameover_text1_rect.top = \ (width - gameover_text1_rect.width) // 2, height // 2 screen.blit(gameover_text1, gameover_text1_rect) gameover_text2 = gameover_font.render(str(score), True, WHITE) gameover_text2_rect = gameover_text2.get_rect() gameover_text2_rect.left, gameover_text2_rect.top = \ (width - gameover_text2_rect.width) // 2, \ gameover_text1_rect.bottom + 10 screen.blit(gameover_text2, gameover_text2_rect) again_rect.left, again_rect.top = \ (width - again_rect.width) // 2, \ gameover_text2_rect.bottom + 50 screen.blit(again_image, again_rect) gameover_rect.left, gameover_rect.top = \ (width - again_rect.width) // 2, \ again_rect.bottom + 10 screen.blit(gameover_image, gameover_rect) # 绘制暂停按钮 screen.blit(pause_image,pause_rect) # 在循环内不断切换,5帧切换一次 if not(delay % 5): switch_image = not switch_image delay -= 1 if not delay: delay = 100 # 更新整个待显示的 Surface 对象到屏幕上 pygame.display.flip() clock.tick(60)
def main(): pygame.mixer.music.play(-1) # Define myPlane hero = myplane.MyPlane(bg_size) # Define enemyPlanes enemies = pygame.sprite.Group() small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, 15) mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, 4) big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 2) clock = pygame.time.Clock() # Define bullet bullet1 = [] bullet1_index = 0 bullet1_num = 5 for i in range(bullet1_num): bullet1.append(bullet.Bullet1(hero.rect.midtop)) # Define super bullet bullet2 = [] bullet2_index = 0 bullet2_num = 10 for i in range(bullet2_num // 2): bullet2.append(bullet.Bullet2((hero.rect.centerx - 32, hero.rect.centery))) bullet2.append(bullet.Bullet2((hero.rect.centerx + 32, hero.rect.centery))) # Plane destroy images index e1_destroy_index = 0 e2_destroy_index = 0 e3_destroy_index = 0 hero_destroy_index = 0 # Score recording score = 0 score_font = pygame.font.Font('Font/font.ttf', 36) # Pause the game paused = False pause_nor_image = pygame.image.load('images/game_pause_nor.png').convert_alpha() pause_pressed_image = pygame.image.load('images/game_pause_pressed.png').convert_alpha() resume_nor_image = pygame.image.load('images/game_resume_nor.png').convert_alpha() resume_pressed_image = pygame.image.load('images/game_resume_pressed.png').convert_alpha() paused_rect = pause_nor_image.get_rect() paused_rect.left = width - paused_rect.width - 10 paused_rect.top = 10 paused_image = pause_nor_image # Setting Game Levels level = 1 # Define bomb bomb_image = pygame.image.load('images/bomb.png').convert_alpha() bomb_rect = bomb_image.get_rect() bomb_font = pygame.font.Font('Font/font.ttf', 48) bomb_num = 3 # Define supply bullet_supply = supply.BulletSupply(bg_size) bomb_supply = supply.BombSupply(bg_size) supply_time = USEREVENT pygame.time.set_timer(supply_time, 5 * 1000) # Set bullet supply timer super_bullet_time = USEREVENT + 1 is_super_bullet = False # Safe timer safe_time = USEREVENT + 2 # hero life life_image = pygame.image.load('images/life.png').convert_alpha() life_rect = life_image.get_rect() life_number = 3 # Limit f_open recorded = False # Game Over Screen gameover_font = pygame.font.Font('Font/font.TTF', 48) restart_image = pygame.image.load('images/restart.png').convert_alpha() restart_rect = restart_image.get_rect() end_game_image = pygame.image.load('images/end_game.png').convert_alpha() end_game_rect = end_game_image.get_rect() # myPlan switch between images switch_image = True # image switch delay delay = 100 running = True while running: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: if event.button == 1 and paused_rect.collidepoint(event.pos): paused = not paused if paused: pygame.time.set_timer(supply_time, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: pygame.time.set_timer(supply_time, 45 * 1000) pygame.mixer.music.unpause() pygame.mixer.unpause() elif event.type == MOUSEMOTION: if paused_rect.collidepoint(event.pos): if paused: paused_image = resume_pressed_image else: paused_image = pause_pressed_image else: if paused: paused_image = resume_nor_image else: paused_image = pause_nor_image elif event.type == KEYDOWN: if event.key == K_SPACE: if bomb_num: bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0: each.active = False elif event.type == supply_time: supply_sound.play() if choice([True, False]): bomb_supply.reset() else: bullet_supply.reset() elif event.type == super_bullet_time: is_super_bullet = False pygame.time.set_timer(super_bullet_time, 0) elif event.type == safe_time: hero.safe = False pygame.time.set_timer(safe_time, 0) # Enemy level upgrade with score if level == 1 and score in range(5000, 50000): level = 2 upgrade_sound.play() # Add four small enemies, 2 mid enemies, and 1 big enemy add_small_enemies(small_enemies, enemies, 4) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) # Increase the speed of small enemies increase_speed(small_enemies, 1) elif level == 2 and score in range(50000, 500000): level = 3 upgrade_sound.play() # Add four small enemies, 2 mid enemies, and 1 big enemy add_small_enemies(small_enemies, enemies, 6) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # Increase the speed of small enemies increase_speed(small_enemies, 1) increase_speed(mid_enemies, 1) elif level == 3 and score in range(500000, 1000000): level = 4 upgrade_sound.play() # Add four small enemies, 2 mid enemies, and 1 big enemy add_small_enemies(small_enemies, enemies, 6) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # Increase the speed of small enemies increase_speed(small_enemies, 1) increase_speed(mid_enemies, 1) screen.blit(background, (0, 0)) if not paused and life_number: # Detect trace of the mouse. key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: hero.moveUp() if key_pressed[K_s] or key_pressed[K_DOWN]: hero.moveDown() if key_pressed[K_a] or key_pressed[K_LEFT]: hero.moveLeft() if key_pressed[K_d] or key_pressed[K_RIGHT]: hero.moveRight() # Show bomb supply if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, hero): get_bomb_sound.play() if bomb_num < 3: bomb_num += 1 bomb_supply.active = False # Show bullet supply if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, hero): get_bullet_sound.play() # Shoot two bullet is_super_bullet = True pygame.time.set_timer(super_bullet_time, 20 * 1000) bullet_supply.active = False # Bullet fire if not(delay % 10): bullet_sound.play() if is_super_bullet: bullets = bullet2 bullets[bullet2_index].reset((hero.rect.centerx - 32, hero.rect.centery)) bullets[bullet2_index + 1].reset((hero.rect.centerx + 32, hero.rect.centery)) bullet2_index = (bullet2_index + 2) % bullet2_num else: bullets = bullet1 bullets[bullet1_index].reset(hero.rect.midtop) bullet1_index = (bullet1_index + 1) % bullet1_num # Bullet collide detection for b in bullets: if b.active: b.move() screen.blit(b.image, b.rect) enemy_hit = pygame.sprite.spritecollide(\ b, enemies, False, pygame.sprite.collide_mask) if enemy_hit: b.active = False for e in enemy_hit: if e in mid_enemies or e in big_enemies: e.hit = True e.energy -= 1 if e.energy == 0: e.active = False else: e.active = False # Generate enemyPlanes # Big enemies for each in big_enemies: if each.active: each.move() if each.hit: # Show hit special effect screen.blit(each.image_hit, each.rect) each.hit = False elif switch_image: screen.blit(each.image1, each.rect) else: screen.blit(each.image2, each.rect) # Showing energy remained pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5), \ (each.rect.right, each.rect.top -5), 2,\ ) # Show GREEN when enemy energy is grater than 20%, else show red energy_remained = each.energy / enemy.BigEnemy.energy if energy_remained > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + each.rect.width * energy_remained, \ each.rect.top - 5), 2) # Play special BGM when big enemy is showing up if each.rect.bottom == -50: enemy3_fly_sound.play(-1) else: # Destroy big enemies if not(delay % 3): if e3_destroy_index == 0: enemy3_down_sound.play() screen.blit(each.destroy_images[e3_destroy_index], each.rect) e3_destroy_index = (e3_destroy_index + 1) % 6 if e3_destroy_index == 0: enemy3_fly_sound.stop() score += 10000 each.reset() # Mid enemies for each in mid_enemies: if each.active: each.move() if each.hit: screen.blit(each.image_hit, each.rect) each.hit = False else: screen.blit(each.image, each.rect) # Showing energy remained pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5), \ (each.rect.right, each.rect.top -5), 2,\ ) # Show GREEN when enemy energy is grater than 20%, else show red energy_remained = each.energy / enemy.MidEnemy.energy if energy_remained > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, \ (each.rect.left, each.rect.top - 5), \ (each.rect.left + each.rect.width * energy_remained, \ each.rect.top - 5), 2) else: # Destroy mid enemies if not(delay % 3): if e2_destroy_index == 0: enemy2_down_sound.play() screen.blit(each.destroy_images[e2_destroy_index], each.rect) e2_destroy_index = (e2_destroy_index + 1) % 4 if e2_destroy_index == 0: score += 6000 each.reset() # Small enemies for each in small_enemies: if each.active: each.move() screen.blit(each.image, each.rect) else: # Destroy small enemies if not(delay % 3): if e1_destroy_index == 0: enemy1_down_sound.play() screen.blit(each.destroy_images[e1_destroy_index], each.rect) e1_destroy_index = (e1_destroy_index + 1) % 4 if e1_destroy_index == 0: score += 1000 each.reset() # Collide detection enemies_down = pygame.sprite.spritecollide(hero, enemies, False, pygame.sprite.collide_mask) if enemies_down and not hero.safe: hero.active = False for e in enemies_down: e.active = False # Generate myPlane if hero.active: if switch_image: screen.blit(hero.image1, hero.rect) else: screen.blit(hero.image2, hero.rect) else: # Destroy hero plane if not(delay % 3): if hero_destroy_index == 0: hero_down_sound.play() screen.blit(hero.destroy_images[hero_destroy_index], hero.rect) hero_destroy_index = (hero_destroy_index + 1) % 4 if hero_destroy_index == 0: life_number -= 1 hero.reset() pygame.time.set_timer(safe_time, 3 * 1000) # Generate bomb remaining image bomb_text = bomb_font.render('X %d' % bomb_num, True, WHITE) text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height)) # Generate remaining life if life_number: for i in range(life_number): screen.blit(life_image, (width - 10 - (i+1)* life_rect.width,\ height - 10 - life_rect.height)) # Game Over Set up elif life_number == 0: # Stop BGM pygame.mixer.music.stop() pygame.mixer.stop() pygame.time.set_timer(supply_time, 0) if not recorded: recorded = True # Show history highest score with open('record.txt', 'r') as f: record_score = int(f.read()) if score > record_score: with open('record.txt', 'w') as f: f.write(str(score)) # Show Gamve Over Screen recorded_score_txt = score_font.render('Highest: %d' % record_score, True, WHITE) screen.blit(recorded_score_txt, (52, 52)) gameover_txt1 = gameover_font.render('Your Score is: ', True, WHITE) gameover_txt1_rect = gameover_txt1.get_rect() gameover_txt1_rect.left = (width - gameover_txt1_rect.width) // 2 gameover_txt1_rect.top = height // 2 screen.blit(gameover_txt1, gameover_txt1_rect) gameover_txt2 = gameover_font.render(str(score), True, WHITE) gameover_txt2_rect = gameover_txt2.get_rect() gameover_txt2_rect.left = (width - gameover_txt2_rect.width) // 2 gameover_txt2_rect.top = gameover_txt1_rect.bottom + 10 screen.blit(gameover_txt2, gameover_txt2_rect) restart_rect.left = (width - restart_rect.width) // 2 restart_rect.bottom = gameover_txt2_rect.bottom + 50 screen.blit(restart_image, restart_rect) end_game_rect.left = (width - restart_rect.width) // 2 end_game_rect.top = restart_rect.bottom + 10 screen.blit(end_game_image, end_game_rect) if pygame.mouse.get_pressed()[0]: position = pygame.mouse.get_pos() if restart_rect.left < position[0] < restart_rect.right and \ restart_rect.top < position[1] < restart_rect.bottom: main() elif end_game_rect.left < position[0] < end_game_rect.right and \ end_game_rect.top < position[1] < end_game_rect.bottom: pygame.quit() sys.exit() # Generate score on screen score_text = score_font.render('Score: %s' % str(score), True, WHITE) screen.blit(score_text, (10, 5)) # Generate pause key screen.blit(paused_image, paused_rect) # Switch between images with delay if not(delay % 5): switch_image = not switch_image delay -= 1 if not delay: delay = 100 pygame.display.flip() clock.tick(60)
def main(): pygame.mixer.music.play(-1) # 生成我方飞机 my_plane = myplane.MyPlane(bg_size) # 存放敌方飞机 enemies = pygame.sprite.Group() # 生成敌方小型飞机 small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, 15) # 生成敌方中型飞机 middle_enemies = pygame.sprite.Group() add_middle_enemies(middle_enemies, enemies, 4) # 生成敌方大型飞机 large_enemies = pygame.sprite.Group() add_large_enemies(large_enemies, enemies, 2) # 生成普通子弹 bullet1 = [] bullet1_index = 0 BULLET1_NUM = 4 for i in range(BULLET1_NUM): bullet1.append(bullet.Bullet1(my_plane.rect.midtop)) # a = [10, 110, 210, 310, 410] # for i in a: # bullet1.append(bullet.Bullent((i, my_plane.rect.height))) # 生成超级子弹 bullet2 = [] bullet2_index = 0 BULLET2_NUM = 8 for i in range(BULLET2_NUM // 2): bullet2.append( bullet.Bullet2( ((my_plane.rect.centerx - 33), my_plane.rect.centery))) bullet2.append( bullet.Bullet2( ((my_plane.rect.centerx + 30), my_plane.rect.centery))) clock = pygame.time.Clock() # 中弹图片索引 small_enemy_destroy_index = 0 middle_enemy_destroy_index = 0 large_enemy_destroy_index = 0 me_destroy_index = 0 # 统计得分 score = 0 score_font = pygame.font.Font('font/font.ttf', 36) # 设置难度级别 level = 1 # 全屏炸弹 bomb_image = pygame.image.load('images/bomb.png').convert_alpha() bomb_rect = bomb_image.get_rect() bomb_font = pygame.font.Font('font/font.ttf', 48) bomb_num = 3 # 每30秒发放一个补给包 bullet_supply = supply.BulletSupply(bg_size) bomb_supply = supply.BombSupply(bg_size) SUPPLY_TIME = USEREVENT pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) # 超级子弹定时器 DOUBLE_BULLET_TIME = USEREVENT + 1 # 是否使用超级子弹 is_double_bullet = False # 解除我方无敌定时器 INVINCIBLE_TIME = USEREVENT + 2 # 我方飞机生命数量 life_image = pygame.image.load('images/life.png').convert_alpha() life_rect = life_image.get_rect() life_num = 3 # 游戏结束画面 gameover_font = pygame.font.Font('font/font.ttf', 48) again_image = pygame.image.load('images/again.png').convert_alpha() again_rect = again_image.get_rect() gameover_image = pygame.image.load('images/gameover.png').convert_alpha() gameover_rect = gameover_image.get_rect() # 用于阻止重复打开记录文件 recorded = False # 标志是否暂停 paused = False pause_nor_image = pygame.image.load('images/pause_nor.png').convert_alpha() pause_pressed_image = pygame.image.load( 'images/pause_pressed.png').convert_alpha() resume_nor_image = pygame.image.load( 'images/resume_nor.png').convert_alpha() resume_pressed_image = pygame.image.load( 'images/resume_pressed.png').convert_alpha() pause_rect = pause_nor_image.get_rect() pause_rect.left, pause_rect.top = width - pause_rect.width - 10, 10 paused_image = pause_nor_image # 用于切换飞机显示图片 switch_image1 = True # 用于切换飞机摧毁图片 switch_image2 = True # 用于延迟 delay = 101 running = True while running: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: if event.button == 1 and pause_rect.collidepoint(event.pos): paused = not paused if paused: pygame.mixer.music.pause() pygame.mixer.pause() pygame.time.set_timer(SUPPLY_TIME, 0) else: pygame.mixer.music.unpause() pygame.mixer.unpause() pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) if pause_rect.collidepoint(event.pos): if paused: paused_image = resume_pressed_image else: paused_image = pause_pressed_image else: if paused: paused_image = resume_nor_image else: paused_image = pause_nor_image elif event.type == MOUSEMOTION: if pause_rect.collidepoint(event.pos): if paused: paused_image = resume_pressed_image else: paused_image = pause_pressed_image else: if paused: paused_image = resume_nor_image else: paused_image = pause_nor_image elif event.type == KEYDOWN: if event.key == K_SPACE: if bomb_num: bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0: each.active = False elif event.type == SUPPLY_TIME: supply_sound.play() if choice([True, False]): bomb_supply.reset() else: bullet_supply.reset() elif event.type == DOUBLE_BULLET_TIME: is_double_bullet = False pygame.time.set_timer(DOUBLE_BULLET_TIME, 0) elif event.type == INVINCIBLE_TIME: my_plane.invincible = False pygame.time.set_timer(INVINCIBLE_TIME, 0) # 根据得分增加难度 if level == 1 and score > 50000: level = 2 upgrade_sound.play() # 增加3架小型敌机,增加2架中型敌机,增加1架大型敌机 add_small_enemies(small_enemies, enemies, 3) add_middle_enemies(middle_enemies, enemies, 2) add_large_enemies(large_enemies, enemies, 1) # 提升小型飞机的速度 increase_speed(small_enemies, 1) elif level == 2 and score > 300000: level = 3 upgrade_sound.play() # 增加5架小型敌机,增加3架中型敌机,增加2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_middle_enemies(middle_enemies, enemies, 3) add_large_enemies(large_enemies, enemies, 2) # 提升小型飞机的速度 increase_speed(small_enemies, 1) increase_speed(middle_enemies, 1) elif level == 3 and score > 600000: level = 4 upgrade_sound.play() # 增加5架小型敌机,增加3架中型敌机,增加2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_middle_enemies(middle_enemies, enemies, 3) add_large_enemies(large_enemies, enemies, 2) # 提升小型飞机的速度 increase_speed(small_enemies, 1) increase_speed(middle_enemies, 1) elif level == 4 and score > 1000000: level = 5 upgrade_sound.play() # 增加5架小型敌机,增加3架中型敌机,增加2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_middle_enemies(middle_enemies, enemies, 3) add_large_enemies(large_enemies, enemies, 2) # 提升小型飞机的速度 increase_speed(small_enemies, 1) increase_speed(middle_enemies, 1) # 绘制背景 screen.blit(background, (0, 0)) # 绘制暂停键 screen.blit(paused_image, pause_rect) # 切换飞机显示图片 if not (delay % 5): switch_image1 = not switch_image1 # 切换飞机摧毁图片 if not (delay % 3): switch_image2 = False else: switch_image2 = True if not delay: delay = 100 else: delay -= 1 # 不暂停时绘制物体 if life_num and not paused: # 检测用户的键盘操作 key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: my_plane.moveUp() if key_pressed[K_s] or key_pressed[K_DOWN]: my_plane.moveDown() if key_pressed[K_a] or key_pressed[K_LEFT]: my_plane.moveLeft() if key_pressed[K_d] or key_pressed[K_RIGHT]: my_plane.moveRight() # 绘制补给并检测是否获得 if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, my_plane): get_bomb_sound.play() if bomb_num < 3: bomb_num += 1 bomb_supply.active = False # 绘制超级子弹并检测是否获得 if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, my_plane): get_bullet_sound.play() is_double_bullet = True pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000) bullet_supply.active = False # 检测我方飞机是否被撞 enemies_down = pygame.sprite.spritecollide( my_plane, enemies, False, pygame.sprite.collide_mask) if enemies_down and not my_plane.invincible: my_plane.active = False for each in enemies_down: each.active = False # 绘制我方飞机 if my_plane.active: if switch_image1: screen.blit(my_plane.image1, my_plane.rect) else: screen.blit(my_plane.image2, my_plane.rect) else: # 毁灭 if not switch_image2: if me_destroy_index == 0: me_down_sound.play() screen.blit(my_plane.destroy_images[me_destroy_index], my_plane.rect) me_destroy_index = (me_destroy_index + 1) % 4 if me_destroy_index == 0: life_num -= 1 my_plane.reset() pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000) # 发射子弹 if not (delay % 10): bullet_sound.play() if is_double_bullet: bullets = bullet2 bullets[bullet2_index].reset( (my_plane.rect.centerx - 33, my_plane.rect.centery)) bullets[bullet2_index + 1].reset( (my_plane.rect.centerx + 30, my_plane.rect.centery)) bullet2_index = (bullet2_index + 2) % BULLET2_NUM else: bullets = bullet1 bullets[bullet1_index].reset(my_plane.rect.midtop) bullet1_index = (bullet1_index + 1) % BULLET1_NUM # 检测子弹是否击中敌机 for b in bullets: if b.active: b.move() screen.blit(b.image, b.rect) enemy_hit = pygame.sprite.spritecollide( b, enemies, False, pygame.sprite.collide_mask) if enemy_hit: b.active = False for e in enemy_hit: if e in middle_enemies or e in large_enemies: e.energy -= 1 if e.energy == 0: e.active = False e.hit = True else: e.active = False # 绘制大型敌方飞机 for each in large_enemies: if each.active: each.move() if each.hit: screen.blit(each.image_hit, each.rect) each.hit = False else: if switch_image1: screen.blit(each.image1, each.rect) if not switch_image1: screen.blit(each.image2, each.rect) # 绘制血槽 pygame.draw.line(screen, BLACK, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) # 当生命大于20%显示绿色,否则显示红色 energy_remain = each.energy / enemy.LargeEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line( screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + energy_remain * each.rect.width, each.rect.top - 5), 2) # 即将出现在画面中,播放音效 if -50 < each.rect.bottom < 0: enemy3_fly_sound.play() else: # 毁灭 if not switch_image2: if large_enemy_destroy_index == 0: enemy3_down_sound.play() screen.blit( each.destroy_images[large_enemy_destroy_index], each.rect) large_enemy_destroy_index = ( large_enemy_destroy_index + 1) % 6 if large_enemy_destroy_index == 0: score += 10000 each.reset() # 绘制中型敌方飞机 for each in middle_enemies: if each.active: each.move() if each.hit: screen.blit(each.image_hit, each.rect) each.hit = False else: screen.blit(each.image, each.rect) # 绘制血槽 pygame.draw.line(screen, BLACK, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) # 当生命大于20%显示绿色,否则显示红色 energy_remain = each.energy / enemy.MiddleEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line( screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + energy_remain * each.rect.width, each.rect.top - 5), 2) else: # 毁灭 if not switch_image2: if middle_enemy_destroy_index == 0: enemy2_down_sound.play() screen.blit( each.destroy_images[middle_enemy_destroy_index], each.rect) middle_enemy_destroy_index = ( middle_enemy_destroy_index + 1) % 4 if middle_enemy_destroy_index == 0: score += 6000 each.reset() # 绘制小型敌方飞机 for each in small_enemies: if each.active: each.move() screen.blit(each.image, each.rect) else: # 毁灭 enemy1_down_sound.play() if not switch_image2: if small_enemy_destroy_index == 0: enemy1_down_sound.play() screen.blit( each.destroy_images[small_enemy_destroy_index], each.rect) small_enemy_destroy_index = ( small_enemy_destroy_index + 1) % 4 if small_enemy_destroy_index == 0: score += 1000 each.reset() # 绘制炸弹数量 bomb_text = bomb_font.render('× %d' % bomb_num, True, WHITE) bomb_text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit( bomb_text, (20 + bomb_rect.width, height - 5 - bomb_text_rect.height)) # 绘制剩余生命数量 if life_num: for i in range(life_num): screen.blit(life_image, (width - 10 - (i + 1) * life_rect.width, height - 10 - life_rect.height)) # 绘制分数 score_text = score_font.render('Score : %s' % str(score), True, WHITE) screen.blit(score_text, (10, 5)) elif life_num and paused: # 绘制分数 score_text = score_font.render('Score : %s' % str(score), True, WHITE) screen.blit(score_text, (10, 5)) # 游戏结束 elif life_num == 0: # 背景音乐停止 pygame.mixer.music.stop() # 停止全部音效 pygame.mixer.stop() # 停止发放补给 pygame.time.set_timer(SUPPLY_TIME, 0) if not recorded: recorded = True # 读取历史最高得分 with open('record.txt', 'r') as f: record_score = int(f.read()) # 如果玩家得分高于历史最高得分,则存档 if score > record_score: with open('record.txt', 'w') as f: f.write(str(score)) # 界面绘制 screen.blit(background, (0, 0)) record_score_text = score_font.render('Best : %d' % record_score, True, WHITE) screen.blit(record_score_text, (10, 10)) gameover_text1 = gameover_font.render('Your Score', True, WHITE) gameover_text1_rect = gameover_text1.get_rect() gameover_text1_rect.left, gameover_text1_rect.top = ( width - gameover_text1_rect.width) // 2, height // 4 screen.blit(gameover_text1, gameover_text1_rect) gameover_text2 = gameover_font.render(str(score), True, WHITE) gameover_text2_rect = gameover_text2.get_rect() gameover_text2_rect.left, gameover_text2_rect.top = (width - gameover_text2_rect.width) // 2, \ gameover_text1_rect.bottom + 10 screen.blit(gameover_text2, gameover_text2_rect) again_rect.left, again_rect.top = ( width - again_rect.width) // 2, gameover_text2_rect.bottom + 50 screen.blit(again_image, again_rect) gameover_rect.left, gameover_rect.top = ( width - gameover_rect.width) // 2, again_rect.bottom + 10 screen.blit(gameover_image, gameover_rect) # 检测玩家鼠标按键操作 # 如果玩家按下左键 if pygame.mouse.get_pressed()[0]: # 获取鼠标坐标 pos = pygame.mouse.get_pos() # 如果点击重新开始 if again_rect.left < pos[ 0] < again_rect.right and again_rect.top < pos[ 1] < again_rect.bottom: main() # 如果点击游戏结束 elif gameover_rect.left < pos[ 0] < gameover_rect.right and gameover_rect.top < pos[ 1] < gameover_rect.bottom: sys.exit() pygame.display.flip() clock.tick(60)
def main(): pygame.init() pygame.mixer.init() # 创建设置实例 ai_settings = Settings() screen = pygame.display.set_mode((ai_settings.bg_width, ai_settings.bg_height)) background = pygame.image.load("images/background.png").convert() pygame.display.set_caption("飞机大战 -- 代码重构版") # 创建音乐、音效实例 sound = Sound() pygame.mixer.music.play(-1) # 创建游戏状态实例 stats = Stats(ai_settings) # 创建计时器实例 timer = Timer() # 创建button实例 button = Button(ai_settings) # 创建字体实例 font = Font() # 生成我方飞机 me = myplane.MyPlane(ai_settings) # 生成地方飞机 enemies = Group() small_enemies = Group() mid_enemies = Group() big_enemies = Group() gf.add_enemies(ai_settings, small_enemies, mid_enemies, big_enemies, enemies) # 生成子弹 bullet1 = [] bullet2 = [] gf.create_bullets(ai_settings, me, bullet1, bullet2) clock = pygame.time.Clock() # 每30秒发放一个补给包 bullet_supply = supply.BulletSupply(ai_settings) bomb_supply = supply.BombSupply(ai_settings) pygame.time.set_timer(timer.SUPPLY_TIME, 30 * 1000) running = True while running: # 响应鼠标和键盘事件 gf.check_events(ai_settings, me, stats, bomb_supply, bullet_supply, sound, timer, button, enemies) # 根据用户的得分增加难度 gf.level_up(ai_settings, stats, sound, small_enemies, mid_enemies, big_enemies, enemies) # 背景图像先绘制,防止通过暂停作弊 screen.blit(background, (0, 0)) if me.life_num: # 绘制暂停按钮 screen.blit(button.paused_image, button.paused_rect) if me.life_num and not stats.paused: # 控制飞机 gf.control_plane(me) # 绘制全屏炸弹补给并检测是否获得 gf.check_bomb_supply(screen, sound, me, bomb_supply) # 绘制超级子弹补给并检测是否获得 gf.check_bullet_supply(ai_settings, screen, sound, me, timer, bullet_supply) # 发射子弹 if not (ai_settings.delay % 10): bullets = gf.fire_bullets(ai_settings, sound, me, bullet1, bullet2) # 检测子弹是否击中敌机 gf.check_hit_enemies(screen, bullets, mid_enemies, big_enemies, enemies) # 绘制敌机 gf.create_enemies(ai_settings, screen, sound, stats, big_enemies, mid_enemies, small_enemies) # 绘制我方飞机 gf.create_my_plane(ai_settings, screen, sound, me, timer) # 检测我方飞机是否被撞 gf.check_my_plane_hit(me, enemies) # 更新游戏界面 gf.update_play_screen(ai_settings, screen, font, button, stats, me, bomb_supply) # 绘制游戏结束画面 elif me.life_num == 0: gf.update_end_screen(ai_settings, screen, font, button, stats, timer, main) # 切换我方飞机图片 gf.switch_image(ai_settings) gf.change_delay(ai_settings) pygame.display.flip() clock.tick(60)
def main(): clock = pygame.time.Clock() switch_image = False delay = 60 running = True pygame.mixer.music.play(-1) me = player.MyPlane(bg_size) # player's plane score = 0 paused = False # pausing function pause_nor_image = pygame.image.load( "image/game_pause_nor.png") # pause button pause_pressed_image = pygame.image.load("image/game_pause_pressed.png") resume_nor_image = pygame.image.load("image/game_resume_nor.png") resume_pressed_image = pygame.image.load("image/game_resume_pressed.png") paused_rect = pause_nor_image.get_rect() paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10 paused_image = pause_nor_image score_font = pygame.font.SysFont("arial", 48) color_black = (0, 0, 0) color_green = (0, 255, 0) color_red = (255, 0, 0) color_white = (255, 255, 255) bomb_image = pygame.image.load("image/bomb.png") bomb_rect = bomb_image.get_rect() bomb_front = score_font bomb_num = 3 # bomb level = 1 # game difficulty life_image = pygame.image.load("image/life.png").convert() life_rect = life_image.get_rect() life_num = 3 # life invincible_time = USEREVENT + 2 # invincible time flag_recorded = False gameover_image = pygame.image.load( "image/game_over.png") # game over picture gameover_rect = gameover_image.get_rect() # normal bullet bullet1 = [] bullet1_index = 0 bullet1_num = 6 # the number of bullets for i in range(bullet1_num): bullet1.append(bullet.Bullet1(me.rect.midtop)) # double bullet double_bullet_timer = USEREVENT + 1 # double bullet existing time is_double_bullet = False bullet2 = [] bullet2_index = 0 bullet2_num = 10 # number of the double bullet for i in range(bullet2_num // 2): bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery))) bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery))) # enemy generated enemies = pygame.sprite.Group() small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, 1) # small enemy generated mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, 1) # mid enemy generated big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 1) # big enemy generated # supply bullet_supply = supply.BulletSupply(bg_size) bomb_supply = supply.BombSupply(bg_size) supply_timer = USEREVENT # supply time set pygame.time.set_timer(supply_timer, 10 * 1000) # plane destruction e1_destroy_index = 0 e2_destroy_index = 0 e3_destroy_index = 0 me_destroy_index = 0 # running process while running: screen.blit(background, (0, 0)) score_text = score_font.render("Score : %s" % str(score), True, color_white) screen.blit(score_text, (10, 5)) # Difficulty increasing if level == 1 and score > 5000: # if reach the second difficulty level, add 3 more small enemy, 2 more mid enemy and 1 more big enemy, increase enemy speed level = 2 level_up_sound.play() add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) inc_speed(small_enemies, 1) elif level == 2 and score > 30000: # if reach the third difficulty level level = 3 level_up_sound.play() add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) inc_speed(small_enemies, 1) inc_speed(mid_enemies, 1) elif level == 3 and score > 60000: # if reach the forth difficulty level level = 4 level_up_sound.play() add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) inc_speed(small_enemies, 1) inc_speed(mid_enemies, 1) inc_speed(big_enemies, 1) # pause detection for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: button_down_sound.play() if event.button == 1 and paused_rect.collidepoint(event.pos): paused = not paused if paused: paused_image = resume_pressed_image pygame.time.set_timer(supply_timer, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: paused_image = pause_pressed_image pygame.time.set_timer(supply_timer, 30 * 1000) pygame.mixer.music.unpause() pygame.mixer.unpause() elif event.type == MOUSEMOTION: if paused_rect.collidepoint(event.pos): if paused: paused_image = resume_pressed_image else: paused_image = pause_pressed_image else: if paused: paused_image = resume_nor_image else: paused_image = pause_nor_image elif event.type == KEYDOWN: if event.key == K_SPACE: # teh use of bombs if bomb_num: bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0: # destroy all enemy each.active = False elif event.type == supply_timer: if choice([True, False]): bomb_supply.reset() else: bullet_supply.reset() elif event.type == double_bullet_timer: is_double_bullet = False pygame.time.set_timer(double_bullet_timer, 0) elif event.type == invincible_time: me.invincible = False pygame.time.set_timer(invincible_time, 0) screen.blit(paused_image, paused_rect) if life_num and (not paused): # number of bombs and life bomb_text = bomb_front.render("× %d" % bomb_num, True, color_black) bomb_text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit( bomb_text, (20 + bomb_rect.width, height - 10 - bomb_text_rect.height)) if life_num: for i in range(life_num): screen.blit(life_image, (width - 10 - (i + 1) * life_rect.width, height - 10 - life_rect.height)) # keyboard control key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: me.move_up() if key_pressed[K_s] or key_pressed[K_DOWN]: me.move_down() if key_pressed[K_a] or key_pressed[K_LEFT]: me.move_left() if key_pressed[K_d] or key_pressed[K_RIGHT]: me.move_right() if not (delay % 10): # every 10 frames, shoot one bullet bullet_sound.play() if not is_double_bullet: bullets = bullet1 bullets[bullet1_index].reset(me.rect.midtop) bullet1_index = (bullet1_index + 1) % bullet1_num else: bullets = bullet2 bullets[bullet2_index].reset( (me.rect.centerx - 33, me.rect.centery)) bullets[bullet2_index + 1].reset( (me.rect.centerx + 30, me.rect.centery)) bullet2_index = (bullet2_index + 2) % bullet2_num # supply receiving detection if bomb_supply.active: # bomb supply bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, me): get_bomb_sound.play() if bomb_num < 3: bomb_num += 1 bomb_supply.active = False if bullet_supply.active: # double bullet supply bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, me): get_bullet_sound.play() is_double_bullet = True pygame.time.set_timer(double_bullet_timer, 18 * 1000) bullet_supply.active = False # collision detection(bullet) for b in bullets: if b.active: b.move() screen.blit(b.image, b.rect) enemies_hit = pygame.sprite.spritecollide( b, enemies, False, pygame.sprite.collide_mask) if enemies_hit: b.active = False for e in enemies_hit: if e in big_enemies or e in mid_enemies: e.energy -= 1 e.hit = True if e.energy == 0: e.active = False else: e.active = False # collision detection(player's plane) enemies_down = pygame.sprite.spritecollide( me, enemies, False, pygame.sprite.collide_mask) if enemies_down and not me.invincible: me.active = False for e in enemies_down: e.active = False # set dynamic effect of player's plane if delay == 0: delay = 60 delay -= 1 if not delay % 3: switch_image = not switch_image if me.active: if switch_image: screen.blit(me.image1, me.rect) else: screen.blit(me.image2, me.rect) else: if not (delay % 3): screen.blit(me.destroy_images[me_destroy_index], me.rect) me_destroy_index = (me_destroy_index + 1) % 4 if me_destroy_index == 0: me_down_sound.play() life_num -= 1 me.reset() # player's plane reborn pygame.time.set_timer(invincible_time, 3 * 1000) # the motion of enemy for each in big_enemies: if each.active: each.move() if not each.hit: if switch_image: screen.blit(each.image1, each.rect) else: screen.blit(each.image2, each.rect) else: screen.blit(each.image_hit, each.rect) each.hit = False # HP display(big enemy) pygame.draw.line(screen, color_black, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) energy_remain = each.energy / enemy.BigEnemy.energy if energy_remain > 0.2: energy_color = color_green else: energy_color = color_red pygame.draw.line( screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) if each.rect.bottom == -50: big_enemy_flying_sound.play(-1) # destruction of enemy and adding scorce(big enemy) else: big_enemy_flying_sound.stop() if e3_destroy_index == 0: enemy3_down_sound.play() if not (delay % 3): screen.blit(each.destroy_images[e3_destroy_index], each.rect) e3_destroy_index = (e3_destroy_index + 1) % 6 if e3_destroy_index == 0: score += 6000 each.reset() # HP display(mid enemy) for each in mid_enemies: if each.active: each.move() if not each.hit: screen.blit(each.image, each.rect) else: screen.blit(each.image_hit, each.rect) each.hit = False pygame.draw.line(screen, color_black, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) energy_remain = each.energy / enemy.MidEnemy.energy if energy_remain > 0.2: energy_color = color_green # destruction of enemy and adding scorce(big enemy) else: energy_color = color_red pygame.draw.line( screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) else: if e2_destroy_index == 0: enemy2_down_sound.play() if not (delay % 3): screen.blit(each.destroy_images[e2_destroy_index], each.rect) e2_destroy_index = (e2_destroy_index + 1) % 4 if e2_destroy_index == 0: score += 2000 each.reset() # destruction of enemy and adding scorce(small enemy) for each in small_enemies: if each.active: each.move() screen.blit(each.image, each.rect) else: if e1_destroy_index == 0: enemy1_down_sound.play() if not (delay % 3): screen.blit(each.destroy_images[e1_destroy_index], each.rect) e1_destroy_index = (e1_destroy_index + 1) % 4 if e1_destroy_index == 0: score += 500 each.reset() # game over elif life_num == 0: screen.blit(gameover_image, gameover_rect) pygame.mixer.music.stop() pygame.mixer.stop() pygame.time.set_timer(supply_timer, 0) if not flag_recorded: # flag_recorded = True with open("score_record.txt", "r") as f: record_score = int(f.read()) if score > record_score: with open("score_record.txt", "w") as f: f.write(str(score)) record_score_text = score_font.render("%d" % record_score, True, color_white) screen.blit(record_score_text, (150, 25)) game_over_score_text = score_font.render("%d" % score, True, color_white) screen.blit(game_over_score_text, (180, 370)) pygame.display.flip() clock.tick(60)
def main(): pygame.mixer.music.play(-1) # 生成我方飞机 me = my_plane.MyPlane(bg_size) # 敌机组 enemies = pygame.sprite.Group() # 生成敌方小飞机 small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, 15) # 生成敌方中飞机 mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, 4) # 生成敌方大飞机 big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 2) # 生成普通子弹 bullet1 = [] bullet1_index = 0 bullet1_num = 4 for i in range(bullet1_num): bullet1.append(bullet.Bullet1(me.rect.midtop)) # 生成超级子弹 bullet2 = [] bullet2_index = 0 bullet2_num = 8 for i in range(bullet2_num // 2): bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery))) bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery))) # 中弹图片索引 e1_destroy_index = 0 e2_destroy_index = 0 e3_destroy_index = 0 me_destroy_index = 0 # 统计得分 score = 0 score_font = pygame.font.Font('font/font.ttf', 36) # 设置字体 clock = pygame.time.Clock() # 标志是否暂停游戏 paused = False # 载入暂停按钮图片 pause_nor_image = pygame.image.load_extended('images/pause_nor.png').convert_alpha() pause_pressed_image = pygame.image.load_extended('images/pause_pressed.png').convert_alpha() resume_nor_image = pygame.image.load_extended('images/resume_nor.png').convert_alpha() resume_pressed_image = pygame.image.load_extended('images/resume_pressed.png').convert_alpha() paused_rect = pause_nor_image.get_rect() paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10 paused_image = pause_nor_image # 设置游戏级别 level = 1 # 全屏炸弹 bomb_image = pygame.image.load_extended('images/bomb.png') bomb_rect = bomb_image.get_rect() bomb_font = pygame.font.Font('font/font.ttf', 48) bomb_num = 3 # 每30秒发放一个补给包 bullet_supply = supply.BulletSupply(bg_size) bomb_supply = supply.BombSupply(bg_size) # 设置定时器 supply_time = USEREVENT # 自定义事件 # 将此自定义时间设置时间为20秒 pygame.time.set_timer(supply_time, 30 * 1000) # 超级子弹定时器 double_bullet_time = USEREVENT + 1 # 接触我方无敌状态定时器 invincible_time = USEREVENT + 2 # 标志是否使用超级子弹 is_double_bullet = False # 生命数量 life_image = pygame.image.load_extended('images/life.png').convert_alpha() life_rect = life_image.get_rect() life_num = 3 # 用于阻止重复打开记录文件 recorded = False # 游戏结束画面 game_over_font = pygame.font.Font('font/font.ttf', 48) again_image = pygame.image.load_extended('images/again.png').convert_alpha() again_rect = again_image.get_rect() game_over_image = pygame.image.load_extended('images/gameover.png').convert_alpha() game_over_rect = game_over_image.get_rect() # 切换飞机图片 switch_image = True # 用于延迟 delay = 100 running = True while running: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: if event.button == 1 and paused_rect.collidepoint(event.pos): # 检测鼠标是否在paused_rect区域 paused = not paused if paused: # 补给暂停 pygame.time.set_timer(supply_time, 0) # 音乐暂停 pygame.mixer.music.pause() # 音效暂停 pygame.mixer.pause() else: pygame.time.set_timer(supply_time, 30 * 1000) pygame.mixer.music.unpause() pygame.mixer.unpause() elif event.type == MOUSEMOTION: if paused_rect.collidepoint(event.pos): if paused: paused_image = resume_pressed_image else: paused_image = pause_pressed_image else: if paused: paused_image = resume_nor_image else: paused_image = pause_nor_image elif event.type == KEYDOWN: if event.key == K_SPACE: if bomb_num: bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0: each.active = False elif event.type == supply_time: supply_sound.play() if choice([True, False]): bomb_supply.reset() else: bullet_supply.reset() elif event.type == double_bullet_time: is_double_bullet = False # 关闭定时器 pygame.time.set_timer(double_bullet_time, 0) elif event.type == invincible_time: me.invincible = False pygame.time.set_timer(invincible_time, 0) if level == 1 and score > 50000: level = 2 up_grade_sound.play() # 增加3架小型敌机,2架中型敌机,1架大型敌机 add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) # 提升小型敌机的速度 increase_speed(small_enemies, 1) elif level == 2 and score > 300000: level = 3 up_grade_sound.play() # 增加5架小型敌机,3架中型敌机,2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # 提升小型、中型敌机的速度 increase_speed(small_enemies, 1) increase_speed(mid_enemies, 1) elif level == 3 and score > 600000: level = 4 up_grade_sound.play() # 增加5架小型敌机,3架中型敌机,2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # 提升小型、中型敌机的速度 increase_speed(small_enemies, 1) increase_speed(mid_enemies, 1) elif level == 4 and score >1000000: level = 5 up_grade_sound.play() # 增加5架小型敌机,3架中型敌机,2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # 提升小型、中型敌机的速度 increase_speed(small_enemies, 1) increase_speed(mid_enemies, 1) # 绘制背景图片 screen.blit(background, (0, 0)) if life_num and not paused: # 检测用户键盘操作 key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: me.move_up() if key_pressed[K_s] or key_pressed[K_DOWN]: me.move_down() if key_pressed[K_a] or key_pressed[K_LEFT]: me.move_left() if key_pressed[K_d] or key_pressed[K_RIGHT]: me.move_right() # 绘制全屏炸弹补给并检测是否获得 if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, me): get_bomb_sound.play() if bomb_num < 3: bomb_num += 1 bomb_supply.active = False # 绘制超级子弹补给并检测是否获得 if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, me): get_bullet_sound.play() # 发射超级子弹 is_double_bullet = True pygame.time.set_timer(double_bullet_time, 18 * 1000) bullet_supply.active = False # 每10帧发射一颗子弹 if not (delay % 10): bullet_sound.play() if is_double_bullet: bullets = bullet2 bullets[bullet2_index].reset((me.rect.centerx - 33, me.rect.centery)) bullets[bullet2_index + 1].reset((me.rect.centerx + 30, me.rect.centery)) bullet2_index = (bullet2_index + 2) % bullet2_num else: bullets = bullet1 bullets[bullet1_index].reset(me.rect.midtop) bullet1_index = (bullet1_index + 1) % bullet1_num # 检测子弹是否击中敌机 for b in bullets: if b.active: b.move() screen.blit(b.image, b.rect) enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask) if enemy_hit: b.active = False for e in enemy_hit: if e in mid_enemies or e in big_enemies: e.hit = True e.energy -= 1 if e.energy == 0: e.active = False else: e.active = False # 绘制大型敌机 for each in big_enemies: if each.active: # 存活 each.move() if each.hit: # 如果被击中 # 绘制被打到的画面 screen.blit(each.image_hit, each.rect) each.hit = False else: if switch_image: screen.blit(each.image1, each.rect) else: screen.blit(each.image2, each.rect) # 绘制血槽 pygame.draw.line(screen, black, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) # #当生命大于20%显示绿色,否则显示红色 energy_remain = each.energy / enemy.BigEnemy.energy if energy_remain > 0.2: energy_color = green else: energy_color = red pygame.draw.line(screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) # 即将出现在画面中, 播放音效 if each.rect.bottom == -50: enemy3_fly_sound.play(-1) else: # 毁灭 if not (delay % 3): if e3_destroy_index == 0: enemy3_down_sound.play() screen.blit(each.destroy_images[e3_destroy_index], each.rect) e3_destroy_index = (e3_destroy_index + 1) % 6 if e3_destroy_index == 0: enemy3_fly_sound.stop() score += 10000 each.reset() # 绘制中型敌机 for each in mid_enemies: if each.active: each.move() if each.hit: # 如果被打到 # 绘制被打到的画面 screen.blit(each.image_hit, each.rect) else: # 绘制正常画面 screen.blit(each.image, each.rect) # 绘制血槽 pygame.draw.line(screen, black, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) # 当生命大于20%显示绿色,否则显示红色 energy_remain = each.energy / enemy.MidEnemy.energy if energy_remain > 0.2: energy_color = green else: energy_color = red pygame.draw.line(screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) else: # 毁灭 if not (delay % 3): if e2_destroy_index == 0: enemy2_down_sound.play() screen.blit(each.destroy_images[e2_destroy_index], each.rect) e2_destroy_index = (e2_destroy_index + 1) % 4 if e2_destroy_index == 0: score += 6000 each.reset() # 绘制小型敌机 for each in small_enemies: if each.active: each.move() screen.blit(each.image, each.rect) else: # 毁灭 if not (delay % 3): if e1_destroy_index == 0: enemy1_down_sound.play() screen.blit(each.destroy_images[e1_destroy_index], each.rect) e1_destroy_index = (e1_destroy_index + 1) % 4 if e1_destroy_index == 0: score += 1000 each.reset() # 检测我方飞机是否被撞 enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask) if enemies_down and not me.invincible: me.active = False for e in enemies_down: e.active = False # 绘制我放飞机 if me.active: if switch_image: screen.blit(me.image1, me.rect) else: screen.blit(me.image2, me.rect) else: # 毁灭 if not (delay % 3): if me_destroy_index == 0: me_down_sound.play() screen.blit(me.destroy_images[me_destroy_index], me.rect) me_destroy_index = (me_destroy_index + 1) % 4 if me_destroy_index == 0: life_num -= 1 me.reset() pygame.time.set_timer(invincible_time, 3 * 1000) # 绘制全屏炸弹数量 bomb_text = bomb_font.render('× %d' % bomb_num, True, white) bomb_text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - bomb_text_rect.height)) # 绘制剩余生命数量 if life_num: for i in range(life_num): screen.blit(life_image, (width - 10 - life_rect.width * (i + 1), height - 10 - life_rect.height)) # 绘制分数 score_text = score_font.render('Score : %s' % str(score), True, white) screen.blit(score_text, (10, 5)) # 绘制游戏结束 elif life_num == 0: # 背景音乐停止 pygame.mixer.music.stop() # 音效停止 pygame.mixer.stop() # 停止发放补给 pygame.time.set_timer(supply_time, 0) if not recorded: recorded = True # 读取历史最高得分 with open('record.txt', 'r') as f: record_score = int(f.read()) # 如果玩家得分高于历史最高得分, 则存档 if score > record_score: with open('record.txt', 'w') as f: f.write(str(score)) # 绘制游戏结束画面 # 绘制最高分数 record_score_text = score_font.render('Best:%d' % record_score, True, (255, 255, 255)) screen.blit(record_score_text, (50, 50)) # 绘制'Your Score' game_over_txt1 = game_over_font.render('Your Score', True, (255, 255, 255)) game_over_txt1_rect = game_over_txt1.get_rect() game_over_txt1_rect.left, game_over_txt1_rect.top = \ (width - game_over_txt1_rect.width) // 2, height // 3 screen.blit(game_over_txt1, game_over_txt1_rect) # 绘制自己得分 game_over_txt2 = game_over_font.render(str(score), True, (255, 255, 255)) game_over_txt2_rect = game_over_txt2.get_rect() game_over_txt2_rect.left, game_over_txt2_rect.top = \ (width - game_over_txt2_rect.width) // 2, game_over_txt1_rect.bottom + 10 screen.blit(game_over_txt2, game_over_txt2_rect) # 绘制重新开始 again_rect.left, again_rect.top = \ (width - again_rect.width) // 2, game_over_txt2_rect.bottom + 50 screen.blit(again_image, again_rect) # 绘制结束游戏 game_over_rect.left, game_over_rect.top = \ (width - game_over_rect.width) // 2, again_rect.bottom + 10 screen.blit(game_over_image, game_over_rect) # 检测用户鼠标操作 # 如果用户按下鼠标左键 if pygame.mouse.get_pressed()[0]: # 获取鼠标坐标 pos = pygame.mouse.get_pos() # 如果用户点击重新开始 if again_rect.left < pos[0] < again_rect.right \ and again_rect.top < pos[1] < again_rect.bottom: # 调用main函数,游戏重新开始 main() # 如果用户点击结束游戏 elif game_over_rect.left < pos[0] < game_over_rect.right \ and game_over_rect.top < pos[1] < game_over_rect.bottom: # 退出游戏 pygame.quit() sys.exit() # 绘制暂停按钮 screen.blit(paused_image, paused_rect) # 切换飞机图片 if not (delay % 5): switch_image = not switch_image delay -= 1 if not delay: delay = 100 pygame.display.flip() clock.tick(60)
def main(): pygame.mixer.music.play(-1) # create player plane object player = playerPlane.MyPlane(screen_size) enemies = pygame.sprite.Group() # generating small class enemy plane smallClassEnemies = pygame.sprite.Group() addSmallClass(smallClassEnemies, enemies, 15) # generating middle class enemy plane middleClassEnemies = pygame.sprite.Group() addMiddleClass(middleClassEnemies, enemies, 4) # generating high class enemy plane highClassEnemies = pygame.sprite.Group() addHighClass(highClassEnemies, enemies, 2) # generate advance bullet advanceBullets = [] advanceBulletIndex = 0 advanceBulletNum = 4 for count in range(advanceBulletNum): advanceBullets.append(weapon.AdvancedBullet(player.rect.midtop)) # generate basic bullet basicBullets = [] basicBulletIndex = 0 basicBulletNum = 4 for count in range(basicBulletNum): basicBullets.append(weapon.BasicBullet(player.rect.midtop)) clock = pygame.time.Clock() # hit image smallEnemyDestroyIndex = 0 midEnemyDestroyIndex = 0 highEnemyDestroyIndex = 0 playerDestroyIndex = 0 run = True #score score = 0 scoreFont = pygame.font.Font("font/font.ttf", 36) #pausing feature pause = False pauseNorImage = pygame.image.load("images/pause_nor.png").convert_alpha() pausePressImage = pygame.image.load( "images/pause_pressed.png").convert_alpha() resumeNorImage = pygame.image.load("images/resume_nor.png").convert_alpha() resumePressImage = pygame.image.load( "images/resume_pressed.png").convert_alpha() pauseRect = pauseNorImage.get_rect() pauseRect.left, pauseRect.top = width - pauseRect.width - 10, 10 pauseImage = pauseNorImage #level of difficulty level = 1 #bomb weapon bombImage = pygame.image.load("images/bomb.png").convert_alpha() bombRect = bombImage.get_rect() bombFont = pygame.font.Font("font/font.ttf", 48) bombNum = 3 #send a supply every 30s bulletSupply = supply.BulletSupply(screen_size) bombSupply = supply.BombSupply(screen_size) timeSupply = USEREVENT pygame.time.set_timer(timeSupply, 30 * 1000) #advancebullet timer advanceBulletTime = USEREVENT + 1 #able to use advancebullet useAdvanceBullet = False #life lifeImage = pygame.image.load("images/life.png").convert_alpha() lifeRect = lifeImage.get_rect() lifeNum = 3 #cancel the invincible mode invincibleTime = USEREVENT + 2 #restrict repeated opening of file recorded = False #game over screen gameoverFont = pygame.font.Font("font/font.ttf", 48) againImage = pygame.image.load("images/again.png").convert_alpha() againRect = againImage.get_rect() gameoverImage = pygame.image.load("images/gameover.png").convert_alpha() gameoverRect = gameoverImage.get_rect() # switch between two player plane image to show exhausion switchImage = True # delay the movement of exhausion delay = 100 while run: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: if event.button == 1 and pauseRect.collidepoint(event.pos): pause = not pause if pause: pygame.time.set_timer(timeSupply, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: pygame.time.set_timer(timeSupply, 30 * 1000) pygame.mixer.music.unpause() pygame.mixer.unpause() elif event.type == MOUSEMOTION: if pauseRect.collidepoint(event.pos): if pause: pauseImage = resumePressImage else: pauseImage = pausePressImage else: if pause: pauseImage = resumeNorImage else: pauseImage = pauseNorImage elif event.type == KEYDOWN: if event.key == K_SPACE: if bombNum: bombNum -= 1 bombSound.play() for each in enemies: if each.rect.bottom > 0: each.active = False elif event.type == timeSupply: supplySound.play() if choice([True, False]): bombSupply.reset() else: bulletSupply.reset() elif event.type == advanceBulletTime: useAdvanceBullet = False pygame.time.set_timer(advanceBulletTime, 0) elif event.type == invincibleTime: player.invincible = False pygame.time.set_timer(invincibleTime, 0) # level increases based on the score if level == 1 and score > 50000: level = 2 upgradeSound.play() #increase 3 low level plane, 2 mid level, 1 high level addSmallClass(smallClassEnemies, enemies, 3) addMiddleClass(middleClassEnemies, enemies, 2) addHighClass(highClassEnemies, enemies, 1) increaseSpeed(smallClassEnemies, 1) elif level == 2 and score > 300000: level = 3 upgradeSound.play() #increase 5 low level plane, 3 mid level, 2 high level addSmallClass(smallClassEnemies, enemies, 5) addMiddleClass(middleClassEnemies, enemies, 3) addHighClass(highClassEnemies, enemies, 2) increaseSpeed(smallClassEnemies, 1) increaseSpeed(middleClassEnemies, 1) elif level == 3 and score > 600000: level = 4 upgradeSound.play() #increase 5 low level plane, 3 mid level, 2 high level addSmallClass(smallClassEnemies, enemies, 5) addMiddleClass(middleClassEnemies, enemies, 3) addHighClass(highClassEnemies, enemies, 2) increaseSpeed(smallClassEnemies, 1) increaseSpeed(middleClassEnemies, 1) elif level == 4 and score > 1000000: level = 5 upgradeSound.play() #increase 5 low level plane, 3 mid level, 2 high level addSmallClass(smallClassEnemies, enemies, 5) addMiddleClass(middleClassEnemies, enemies, 3) addHighClass(highClassEnemies, enemies, 2) increaseSpeed(smallClassEnemies, 1) increaseSpeed(middleClassEnemies, 1) screen.blit(background, (0, 0)) if lifeNum and not pause: # check for user keyboard pressed or not keyPressed = pygame.key.get_pressed() if keyPressed[K_w] or keyPressed[K_UP]: player.up() if keyPressed[K_s] or keyPressed[K_DOWN]: player.down() if keyPressed[K_a] or keyPressed[K_LEFT]: player.left() if keyPressed[K_d] or keyPressed[K_RIGHT]: player.right() #draw bomb supply and check for contact if bombSupply.active: bombSupply.move() screen.blit(bombSupply.image, bombSupply.rect) if pygame.sprite.collide_mask(bombSupply, player): getBombSound.play() if bombNum < 3: bombNum += 1 bombSupply.active = False #draw bomb supply and check for contact if bulletSupply.active: bulletSupply.move() screen.blit(bulletSupply.image, bulletSupply.rect) if pygame.sprite.collide_mask(bulletSupply, player): getBulletSound.play() useAdvanceBullet = True pygame.time.set_timer(advanceBulletTime, 18 * 1000) bulletSupply.active = False #shooting/drawing bullet if not (delay % 10): bulletSound.play() if useAdvanceBullet: bullet = advanceBullets bullet[advanceBulletIndex].resetBullet(player.rect.midtop) advanceBulletIndex = (advanceBulletIndex + 1) % advanceBulletNum else: bullet = basicBullets bullet[basicBulletIndex].resetBullet(player.rect.midtop) basicBulletIndex = (basicBulletIndex + 1) % basicBulletNum # check if bullet hit enemy plane for b in bullet: if b.active: b.move() screen.blit(b.image, b.rect) enenmyHit = pygame.sprite.spritecollide( b, enemies, False, pygame.sprite.collide_mask) if enenmyHit: b.active = False for e in enenmyHit: if e in middleClassEnemies or e in highClassEnemies: e.hit = True e.health -= 1 if e.health == 0: e.active = False else: e.active = False # draw large class enemy plane for plane in highClassEnemies: if plane.active: plane.move() if plane.hit: screen.blit(plane.imageHit, plane.rect) plane.hit = False else: if switchImage: screen.blit(plane.image1, plane.rect) else: screen.blit(plane.image2, plane.rect) # drawing health bar pygame.draw.line(screen, BLACK, \ (plane.rect.left,plane.rect.top-5),\ (plane.rect.right,plane.rect.top-5),2 ) # if health is above 20 percent show green else show red healthProportion = plane.health / enemyPlane.HighClassEnemy.health if healthProportion > 0.2: healthColor = GREEN else: healthColor = RED pygame.draw.line(screen, healthColor, \ (plane.rect.left,plane.rect.top-5),\ (int(plane.rect.left +plane.rect.width*healthProportion),\ plane.rect.top-5),2) # when appearing play music if plane.rect.bottom == -50: enemy3FlySound.play(-1) else: if not (delay % 3): if highEnemyDestroyIndex == 0: #destroy enemy3DownSound.play() screen.blit(plane.destroyImages[highEnemyDestroyIndex], plane.rect) highEnemyDestroyIndex = (highEnemyDestroyIndex + 1) % 6 if highEnemyDestroyIndex == 0: enemy3FlySound.stop() score += 10000 plane.resetPlane() # draw mid class enemy plane for plane in middleClassEnemies: if plane.active: plane.move() if plane.hit: screen.blit(plane.imageHit, plane.rect) plane.hit = False else: screen.blit(plane.image, plane.rect) # drawing health bar pygame.draw.line(screen, BLACK, \ (plane.rect.left,plane.rect.top-5),\ (plane.rect.right,plane.rect.top-5),2 ) # if health is above 20 percent show green else show red healthProportion = plane.health / enemyPlane.MiddleClassEnemy.health if healthProportion > 0.2: healthColor = GREEN else: healthColor = RED pygame.draw.line(screen, healthColor, \ (plane.rect.left,plane.rect.top-5),\ (int(plane.rect.left +plane.rect.width*healthProportion),\ plane.rect.top-5),2) else: if not (delay % 3): if midEnemyDestroyIndex == 0: enemy2DownSound.play() screen.blit(plane.destroyImages[midEnemyDestroyIndex], plane.rect) midEnemyDestroyIndex = (midEnemyDestroyIndex + 1) % 4 if midEnemyDestroyIndex == 0: score += 5000 plane.resetPlane() # draw small class enemy plane for plane in smallClassEnemies: if plane.active: plane.move() screen.blit(plane.image, plane.rect) else: if not (delay % 3): if smallEnemyDestroyIndex == 0: enemy1DownSound.play() screen.blit( plane.destroyImages[smallEnemyDestroyIndex], plane.rect) smallEnemyDestroyIndex = (smallEnemyDestroyIndex + 1) % 4 if smallEnemyDestroyIndex == 0: score += 1000 plane.resetPlane() # checking for any damage done to player hit = pygame.sprite.spritecollide(player, enemies, False, pygame.sprite.collide_mask) if hit and not player.invincible: player.active = False for enemy in hit: enemy.active = False # draw player plane if player.active: if switchImage: screen.blit(player.image1, player.rect) else: screen.blit(player.image2, player.rect) else: if not (delay % 3): if playerDestroyIndex == 0: playerDownSound.play() screen.blit(plane.destroyImages[playerDestroyIndex], player.rect) playerDestroyIndex = (playerDestroyIndex + 1) % 4 if playerDestroyIndex == 0: lifeNum -= 1 player.reset() pygame.time.set_timer(invincibleTime, 3 * 1000) # drawing the bomb bombText = bombFont.render("x %d" % bombNum, True, WHITE) textRect = bombText.get_rect() screen.blit(bombImage, (10, height - 10 - bombRect.height)) screen.blit(bombText, (20 + bombRect.width, height - 5 - textRect.height)) #drawing remaining life if lifeNum: for i in range(lifeNum): screen.blit(lifeImage,\ (width-10-(i+1)*lifeRect.width, \ height-10-lifeRect.height)) #showing the score scoreText = scoreFont.render("Score : %s" % str(score), True, WHITE) screen.blit(scoreText, (10, 5)) #pause sign graphics screen.blit(pauseImage, pauseRect) elif lifeNum == 0: pygame.mixer.music.stop() pygame.mixer.stop() pygame.time.set_timer(timeSupply, 0) if not recorded: recorded = True #get high score with open("record.txt", "r") as file: record = int(file.read()) if score > record: with open("record.txt", "w") as file: file.write(str(score)) record = score # game end interface recordText = scoreFont.render("Best : %d" % record, True, (255, 255, 255)) screen.blit(recordText, (50, 50)) gameover_text1 = gameoverFont.render("Your Score", True, (255, 255, 255)) gameover_text1_rect = gameover_text1.get_rect() gameover_text1_rect.left, gameover_text1_rect.top = ( width - gameover_text1_rect.width) // 2, height // 3 screen.blit(gameover_text1, gameover_text1_rect) gameover_text2 = gameoverFont.render(str(score), True, (255, 255, 255)) gameover_text2_rect = gameover_text2.get_rect() gameover_text2_rect.left, gameover_text2_rect.top = ( width - gameover_text2_rect.width ) // 2, gameover_text1_rect.bottom + 10 screen.blit(gameover_text2, gameover_text2_rect) againRect.left, againRect.top = ( width - againRect.width) // 2, gameover_text2_rect.bottom + 50 screen.blit(againImage, againRect) gameoverRect.left, gameoverRect.top = ( width - againRect.width) // 2, againRect.bottom + 10 screen.blit(gameoverImage, gameoverRect) if pygame.mouse.get_pressed()[0]: pos = pygame.mouse.get_pos() if againRect.left < pos[ 0] < againRect.right and againRect.top < pos[ 1] < againRect.bottom: main() elif gameoverRect.left < pos[ 0] < gameoverRect.right and gameoverRect.top < pos[ 1] < gameoverRect.bottom: pygame.quit() sys.exit() # switch the images to show exhasion if not (delay % 5): switchImage = not switchImage delay -= 1 if not delay: delay = 100 pygame.display.flip() clock.tick(60)
def main(): pygame.mixer.music.play(-1) me_destroy_index = 0 e1_destroy_index = 0 e2_destroy_index = 0 e3_destroy_index = 0 clock = pygame.time.Clock() delay = 60 running = True switch_image = False is_double_bullet = False flag_recorded = False score_font = pygame.font.SysFont("arial", 24) score = 0 level = 1 bomb_num = 3 bomb_image = pygame.image.load("image/bomb.png") bomb_rect = bomb_image.get_rect() bomb_font = score_font life_image = pygame.image.load("image/life.png").convert() life_rect = life_image.get_rect() life_num = 3 supply_timer = USEREVENT pygame.time.set_timer(supply_timer, 10 * 1000) double_bullet_timer = USEREVENT + 1 invincible_time = USEREVENT + 2 me = myplane.MyPlane(bg_size) enemies = pygame.sprite.Group() small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies,1) mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, 1) big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 1) bullet_supply = supply.BulletSupply(bg_size) bomb_supply = supply.BombSupply(bg_size) bullet1 = [] bullet1_index = 0 bullet1_num = 6 for i in range(bullet1_num): bullet1.append(bullet.Bullet1(me.rect.midtop)) bullet2 = [] bullet2_index = 0 bullet2_num = 10 for i in range(bullet2_num // 2): bullet2.append(bullet.Bullet2((me.rect.centerx + 15, me.rect.centery))) bullet2.append(bullet.Bullet2((me.rect.centerx - 15, me.rect.centery))) color_black = (0, 0, 0) color_green = (0, 255, 0) color_red = (255, 0, 0) color_white = (255, 255, 255) paused = False pause_nor_image = pygame.image.load("image/game_pause_nor.png") pause_pressed_image = pygame.image.load("image/game_pause_pressed.png") resume_nor_image = pygame.image.load("image/game_resume_nor.png") resume_pressed_image = pygame.image.load("image/game_resume_pressed.png") paused_rect = pause_nor_image.get_rect() paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10 paused_image = pause_nor_image gameover_image = pygame.image.load("image/game_over.png") gameover_rect = gameover_image.get_rect() gamereload_image = pygame.image.load("image/btn_finish.png") gamereload_rect = gamereload_image.get_rect() gamereload_rect.left, gamereload_rect.top = (width-gamereload_rect.width)//2, 470 while running: clock.tick(60) screen.blit(background, (0, 0)) screen.blit(paused_image, paused_rect) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == KEYDOWN: if event.key == K_SPACE: if bomb_num: bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0: each.active = False elif event.type == supply_timer: if choice([True, False]): bomb_supply.reset() else: bullet_supply.reset() elif event.type == double_bullet_timer: is_double_bullet = False pygame.time.set_timer(double_bullet_timer, 0) elif event.type == invincible_time: me.invincible = False pygame.time.set_timer(invincible_time, 0) elif event.type == MOUSEMOTION: if paused_rect.collidepoint(event.pos): if paused: paused_image = resume_pressed_image else: paused_image = pause_pressed_image else: if paused: paused_image = resume_nor_image else: paused_image = pause_nor_image elif event.type == MOUSEBUTTONDOWN: button_down_sound.play() if event.button == 1 and paused_rect.collidepoint(event.pos): paused = not paused if paused: paused_image = resume_pressed_image pygame.time.set_timer(supply_timer, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: paused_image = pause_pressed_image pygame.time.set_timer(supply_timer, 30 * 1000) pygame.mixer.music.unpause() pygame.mixer.unpause() elif event.button == 1 and gamereload_rect.collidepoint(event.pos): # bg and music init screen.blit(background, (0, 0)) screen.blit(paused_image, paused_rect) pygame.mixer.music.play(-1) # others init pygame.time.set_timer(supply_timer, 10 * 1000) score = 0 level = 1 life_num = 3 bomb_num = 3 flag_recorded = False is_double_bullet = False # clean enemies for each in enemies: if each.rect.bottom > 0: each.active = False enemies.empty() small_enemies.empty() add_small_enemies(small_enemies, enemies, 1) mid_enemies.empty() add_mid_enemies(mid_enemies, enemies, 1) big_enemies.empty() add_big_enemies(big_enemies, enemies, 1) # clean bullet/bomb bomb_supply.active = False bullet_supply.active = False for b in bullets: if b.rect.bottom > 0: b.active = False if life_num and not paused: # draw score score_text = score_font.render("Score: %s" % str(score), True, color_white) screen.blit(score_text, (10, 5)) # draw bomb bomb_text = bomb_font.render("x %d" % bomb_num, True, color_black) bomb_text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - bomb_rect.height - 10)) screen.blit(bomb_text, (20 + bomb_rect.width, height - bomb_text_rect.height - 10)) # draw life for i in range(life_num): screen.blit(life_image, (width - 10 - (i + 1) * life_rect.width, height - 10 - life_rect.height)) # get the keyboard input sequence key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: me.move_up() if key_pressed[K_s] or key_pressed[K_DOWN]: me.move_down() if key_pressed[K_a] or key_pressed[K_LEFT]: me.move_left() if key_pressed[K_d] or key_pressed[K_RIGHT]: me.move_right() # supply set if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, me): get_bomb_sound.play() if bomb_num < 3: bomb_num += 1 bomb_supply.active = False if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, me): get_bullet_sound.play() is_double_bullet = True bullet_supply.active = False pygame.time.set_timer(double_bullet_timer, 15 * 1000) # level upgrade if level == 1 and score > 500: level = 2 level_up_sound.play() add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) inc_speed(small_enemies, 1) elif level == 2 and score > 6000: level = 3 level_up_sound.play() add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) # inc_speed(small_enemies, 1) inc_speed(mid_enemies, 1) elif level == 3 and score > 15000: level = 4 level_up_sound.play() add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) # inc_speed(small_enemies, 1) # inc_speed(mid_enemies, 1) inc_speed(big_enemies, 1) # bullet collide if not (delay % 10): bullet_sound.play() if not is_double_bullet: bullets = bullet1 bullets[bullet1_index].reset(me.rect.midtop) bullet1_index = (bullet1_index + 1) % bullet1_num else: bullets = bullet2 bullets[bullet2_index].reset((me.rect.centerx - 20, me.rect.centery)) bullets[bullet2_index + 1].reset((me.rect.centerx + 12, me.rect.centery)) bullet2_index = (bullet2_index + 2) % bullet2_num for b in bullets: if b.active: b.move() screen.blit(b.image, b.rect) enemies_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask) if enemies_hit: b.active = False for e in enemies_hit: if e in mid_enemies or e in big_enemies: e.energy -= 1 e.hit = True if e.energy == 0: e.active = False else: e.active = False # my plane collide enemy_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask) if enemy_down and not me.invincible: me.active = False for e in enemy_down: e.active = False # my plane display if not (delay % 3): switch_image = not switch_image if me.active: if switch_image: screen.blit(me.image1, me.rect) else: screen.blit(me.image2, me.rect) else: if me_destroy_index == 0: me_down_sound.play() if not (delay % 3): screen.blit(me.destroy_images[me_destroy_index], me.rect) me_destroy_index = (me_destroy_index + 1) % 4 if me_destroy_index == 0: life_num -= 1 me.reset() pygame.time.set_timer(invincible_time, 3 * 1000) # small enemies display for each in small_enemies: if each.active: each.move() screen.blit(each.image, each.rect) else: if e1_destroy_index == 0: enemy1_down_sound.play() if not (delay % 3): screen.blit(each.destroy_images[e1_destroy_index], each.rect) e1_destroy_index = (e1_destroy_index + 1 ) % 4 if e1_destroy_index == 0: score += 50 each.reset() # mid enemies display for each in mid_enemies: if each.active: each.move() # draw plane if not each.hit: screen.blit(each.image, each.rect) else: screen.blit(each.image_hit, each.rect) each.hit = False # draw blood slot pygame.draw.line(screen, color_black, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) energy_remain = each.energy / enemy.MidEnemy.energy if energy_remain > 0.2: energy_color = color_green else: energy_color = color_red pygame.draw.line(screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) # mid plane destroy else: if e2_destroy_index == 0: enemy2_down_sound.play() if not (delay % 3): screen.blit(each.destroy_images[e2_destroy_index], each.rect) e2_destroy_index = (e2_destroy_index + 1) % 4 if e2_destroy_index == 0: score += 200 each.reset() # big enemies display for each in big_enemies: if each.active: each.move() if not each.hit: if switch_image: screen.blit(each.image1, each.rect) else: screen.blit(each.image2, each.rect) else: screen.blit(each.image_hit, each.rect) each.hit = False # draw blood slot pygame.draw.line(screen, color_black, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) energy_remain = each.energy / enemy.BigEnemy.energy if energy_remain > 0.2: energy_color = color_green else: energy_color = color_red pygame.draw.line(screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) if each.rect.bottom == -10: big_enemy_flying_sound.play(-1) # big plane destroy else: if e3_destroy_index == 0: enemy3_down_sound.play() if not (delay % 3): screen.blit(each.destroy_images[e3_destroy_index], each.rect) e3_destroy_index = (e3_destroy_index + 1 ) % 6 if e3_destroy_index == 0: score += 600 each.reset() elif life_num == 0: screen.blit(gameover_image, gameover_rect) screen.blit(gamereload_image, gamereload_rect) pygame.mixer.music.stop() # close bg music pygame.mixer.stop() # close others music pygame.time.set_timer(supply_timer, 0) if not flag_recorded: flag_recorded = True with open("score_record.txt", "r") as f: record_score = int(f.read()) if score > record_score: with open("score_record.txt", "w") as f: f.write(str(score)) record_score_text = score_font.render("%d" % record_score, True, color_white) screen.blit(record_score_text, (150, 40)) game_over_score_text = score_font.render("%d" % score, True, color_white) screen.blit(game_over_score_text, (220, 370)) pygame.display.flip() if delay == 0: delay = 60 delay -= 1
def main(): pygame.mixer.music.play(-1) me = myplane.MyPlane(bg_size) enemies = pygame.sprite.Group() # Initialize small enemies small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, 50) # Initialize mid enemies mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, 15) # Initialize big enemies big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 6) clock = pygame.time.Clock() # Control the aircraft destroy effect small_destroy_index = 0 mid_destroy_index = 0 big_destroy_index = 0 me_destroy_index = 0 # Control the dynamic effect of images switch_image = True delay = 100 # You have three life points life = 3 life_image = pygame.image.load('image/lifejet.png').convert_alpha() life_rect = life_image.get_rect() # Initialize score score = 0 score_font = pygame.font.Font('SentyCreamPuff.ttf', 36) final_score_font = pygame.font.Font('SentyCreamPuff.ttf', 48) # Pause button stuff paused = False pause_regular_image = pygame.image.load( 'image/game_pause_nor.png').convert_alpha() pause_pressed_image = pygame.image.load( 'image/game_pause_pressed.png').convert_alpha() resume_regular_image = pygame.image.load( 'image/game_resume_nor.png').convert_alpha() resume_pressed_image = pygame.image.load( 'image/game_resume_pressed.png').convert_alpha() pause_rect = pause_regular_image.get_rect() pause_rect.left, pause_rect.top = width - pause_rect.width - 5, 5 pause_image = pause_regular_image pause_animation1 = pygame.image.load( 'image/game_loading1.png').convert_alpha() pause_animation2 = pygame.image.load( 'image/game_loading2.png').convert_alpha() pause_animation3 = pygame.image.load( 'image/game_loading3.png').convert_alpha() # Game difficulty level level = 1 # Full Screen bomb! bomb_image = pygame.image.load('image/bomb.png').convert_alpha() bomb_rect = bomb_image.get_rect() bomb_font = pygame.font.Font('SentyCreamPuff.ttf', 48) bomb_num = 0 # Without any bomb at the very beginning # Bomb supply + bullet supply bomb_supply = supply.BombSupply(bg_size) bullet_supply = supply.BulletSupply(bg_size) supply_timer = USEREVENT pygame.time.set_timer(supply_timer, 30 * 1000) # Double bullet timer double_bullet_timer = USEREVENT + 1 is_double_bullets = False # Invincible period timer invincible_timer = USEREVENT + 2 # Create regular bullets bullets1 = [] bullet1_index = 0 bullet_num = 6 for i in range(bullet_num): bullet_position = (me.rect.midtop[0] - 3, me.rect.midtop[1]) bullets1.append(bullet.Bullet(bullet_position)) # Create double bulltes bullets2 = [] bullet2_index = 0 double_num = 8 for i in range(double_num): bullets2.append( bullet.DoubleBullet((me.rect.centerx - 35, me.rect.centery))) bullets2.append( bullet.DoubleBullet((me.rect.centerx + 28, me.rect.centery))) # Set bullets to be regular bullets initially bullets = bullets1 # Play again button again_image = pygame.image.load('image/again.png').convert_alpha() again_rect = again_image.get_rect() again_rect.left += 150 again_rect.top += 450 terminated = False running = True while running: # Draw background screen.blit(background, (0, 0)) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() # Click to pause the game elif event.type == MOUSEBUTTONDOWN: if event.button == 1 and life == 0 and again_rect.collidepoint( event.pos): # Restart the game main() elif event.button == 1 and pause_rect.collidepoint(event.pos): paused = not paused if paused: pygame.time.set_timer(supply_timer, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: pygame.time.set_timer(supply_timer, 30 * 1000) pygame.mixer.music.unpause() pygame.mixer.unpause() # When cursor is moving and interact with the pause button elif event.type == MOUSEMOTION: if pause_rect.collidepoint(event.pos): if paused: pause_image = resume_pressed_image else: pause_image = pause_pressed_image else: if paused: pause_image = resume_regular_image else: pause_image = pause_regular_image # Hit space bar and use the full-screen bomb elif event.type == KEYDOWN: if event.key == K_SPACE: if bomb_num: bomb_num -= 1 for e in enemies: if e.rect.bottom > 0: e.alive = False # Provide a supply every 30s elif event.type == supply_timer: if random.random() > 0.5: bullet_supply.reset() else: bomb_supply.reset() # Double firing period elif event.type == double_bullet_timer: is_double_bullets = False pygame.time.set_timer(double_bullet_timer, 0) elif event.type == invincible_timer: me.invincible = False pygame.time.set_timer(invincible_timer, 0) # Delay effect, avoid image switching too fast delay -= 1 if delay == 0: delay = 100 if not (delay % 10): switch_image = not switch_image # Draw score score_text = score_font.render('Score: %s' % str(score), True, black) screen.blit(score_text, (5, 5)) # Draw pause or resume buttion screen.blit(pause_image, pause_rect) if paused and delay % 33 > 22: screen.blit(pause_animation1, (90, 380)) elif paused and delay % 33 > 11: screen.blit(pause_animation2, (140, 380)) elif paused: screen.blit(pause_animation3, (190, 380)) # Draw bombs bomb_text = bomb_font.render('x %d' % bomb_num, True, black) text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height)) # Draw life points for i in range(life): life_rect.left = width - 50 * (i + 1) life_rect.top = height - 70 screen.blit(life_image, life_rect) # Control the game difficulty level if level == 1 and score > 2000: level = 2 add_small_enemies(small_enemies, enemies, 10) add_mid_enemies(mid_enemies, enemies, 5) add_big_enemies(big_enemies, enemies, 2) increase_speed(small_enemies, 1) if level == 2 and score > 5000: level = 3 #add_small_enemies(small_enemies,enemies,10) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) increase_speed(small_enemies, 1) increase_speed(mid_enemies, 1) if level == 3 and score > 10000: level = 4 #add_small_enemies(small_enemies,enemies,10) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) increase_speed(small_enemies, 1) increase_speed(mid_enemies, 1) increase_speed(big_enemies, 1) # Only play when the game is unpaused if (not paused) and life: # Player's control key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: me.moveUp() if key_pressed[K_s] or key_pressed[K_DOWN]: me.moveDown() if key_pressed[K_a] or key_pressed[K_LEFT]: me.moveLeft() if key_pressed[K_d] or key_pressed[K_RIGHT]: me.moveRight() # Draw bomb supply and test whether player gets it if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, me): get_bomb_sound.play() if bomb_num < 3: bomb_num += 1 bomb_supply.active = False # Draw bullet supply and test whether player gets it if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, me): get_bullet_sound.play() # Double bullets fire! is_double_bullets = True pygame.time.set_timer(double_bullet_timer, 20 * 1000) bullet_supply.active = False # Bullets, both regular and double if is_double_bullets and not (delay % 5): bullet_sound.play() bullets = bullets2 bullets[bullet2_index].reset( (me.rect.centerx - 35, me.rect.centery)) bullets[bullet2_index + 1].reset( (me.rect.centerx + 28, me.rect.centery)) bullet2_index = (bullet2_index + 2) % (double_num * 2) elif not is_double_bullets and not (delay % 10): bullets = bullets1 bullet_position = (me.rect.midtop[0] - 3, me.rect.midtop[1]) bullets[bullet1_index].reset(bullet_position) bullet1_index = (bullet1_index + 1) % bullet_num # Draw bullet and Collision test (bullet and enemy) for b in bullets: if b.active: b.move() screen.blit(b.image, b.rect) enemy_hit = pygame.sprite.spritecollide( b, enemies, False, pygame.sprite.collide_mask) if enemy_hit: b.active = False for e in enemy_hit: if e in mid_enemies or e in big_enemies: e.hit = True e.hp -= 1 if e.hp == 0: e.alive = False else: # If hit a small enemy e.alive = False # Collision test (jet and enemy) crashed = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask) if crashed and not me.invincible: me.alive = False for e in crashed: e.alive = False # Draw big enemies for e in big_enemies: if e.alive: e.move() if e.hit: # Show some damage effects screen.blit(e.image_hit, e.rect) e.hit = False else: if switch_image: screen.blit(e.image, e.rect) else: screen.blit(e.image1, e.rect) if e.rect.bottom == -50: enemy3_fly_sound.play(-1) # Draw hp bar pygame.draw.line(screen, black, \ (e.rect.left, e.rect.bottom + 5), \ (e.rect.right, e.rect.bottom +5), 2) hp_percentage = float(e.hp) / enemy.BigEnemy.hp if hp_percentage > 0.3: hp_color = green else: hp_color = red pygame.draw.line(screen, hp_color, \ (e.rect.left, e.rect.bottom + 5), \ (e.rect.left+e.rect.width*hp_percentage, \ e.rect.bottom + 5), 2) else: # Enemy blows up! # Use the delay effect to entend the time interval among # blow up images, make the blow animation better screen.blit(e.destroy_images[big_destroy_index], e.rect) if not (delay % 3): # Only play the sound once per explosion if big_destroy_index == 0: enemy3_down_sound.play() # Keep the index value between 0 and 5 big_destroy_index = (big_destroy_index + 1) % 6 if big_destroy_index == 0: score += 1000 enemy3_fly_sound.stop() e.reset() # Draw mid enemies for e in mid_enemies: if e.alive: e.move() if e.hit: # Show some damage effects screen.blit(e.image_hit, e.rect) e.hit = False else: screen.blit(e.image, e.rect) # Draw hp bar pygame.draw.line(screen, black, \ (e.rect.left, e.rect.bottom + 5), \ (e.rect.right, e.rect.bottom +5), 2) hp_percentage = float(e.hp) / enemy.MidEnemy.hp if hp_percentage > 0.3: hp_color = green else: hp_color = red pygame.draw.line(screen, hp_color, \ (e.rect.left, e.rect.bottom + 5), \ (e.rect.left+e.rect.width*hp_percentage, \ e.rect.bottom + 5), 2) else: # Enemy blows up! # Use the delay effect to entend the time interval among # blow up images, make the blow animation better screen.blit(e.destroy_images[mid_destroy_index], e.rect) if not (delay % 3): # Only play the sound once per explosion if mid_destroy_index == 0: enemy2_down_sound.play() # Keep the index value between 0 and 3 mid_destroy_index = (mid_destroy_index + 1) % 4 if mid_destroy_index == 0: score += 100 e.reset() # Draw small enemies for e in small_enemies: if e.alive: e.move() screen.blit(e.image, e.rect) else: # Enemy blows up! # Use the delay effect to entend the time interval among # blow up images, make the blow animation better screen.blit(e.destroy_images[small_destroy_index], e.rect) if not (delay % 3): # Only play the sound once per explosion if small_destroy_index == 0: enemy1_down_sound.play() # Keep the index value between 0 and 3 small_destroy_index = (small_destroy_index + 1) % 4 if small_destroy_index == 0: score += 10 e.reset() # Draw hero jet if me.alive and not me.invincible: if switch_image: screen.blit(me.image, me.rect) else: screen.blit(me.image1, me.rect) elif me.alive and me.invincible: if delay % 10 > 4: screen.blit(me.image, me.rect) else: # Hero jet blows up! # Use the delay effect to entend the time interval among # blow up images, make the blow animation better screen.blit(me.destroy_images[me_destroy_index], me.rect) if not (delay % 3): # Only play the sound once per explosion if me_destroy_index == 0: me_down_sound.play() # Keep the index value between 0 and 3 me_destroy_index = (me_destroy_index + 1) % 4 if me_destroy_index == 0: life -= 1 # If has life points, continue playing if life: me.resurrect() pygame.time.set_timer(invincible_timer, 2 * 1000) # No life points left else: print('Game Over!') elif not life: # Only conduct the following procedure once if not terminated: terminated = True # Terminate some stuff pygame.mixer.music.stop() pygame.mixer.stop() pygame.time.set_timer(supply_timer, 0) # Historical highest score if not os.path.exists('record.txt'): best_score = 0 else: with open('record.txt', 'r') as f: best_score = int(f.read()) f.close() if score > best_score: best_score = score print(best_score) with open('record.txt', 'w') as f: f.write(str(score)) f.close() #gameover_image = pygame.image.load('image/background.png').convert_alpha() final_score_text = final_score_font.render( 'Final Score: %s' % str(score), True, black) best_score_text = score_font.render( 'Highest Score: {}'.format(best_score), True, black) again_image = pygame.image.load('image/again.png').convert_alpha() again_rect = again_image.get_rect() again_rect.left += 150 again_rect.top += 400 screen.blit(background, (0, 0)) screen.blit(best_score_text, (20, 20)) screen.blit(final_score_text, (70, 270)) screen.blit(again_image, again_rect) pygame.display.flip() clock.tick(60) '''
def main(): clock = pygame.time.Clock() # 设置帧率 switch_image = False # 控制飞机图片切换的标志位(用以模拟发动机喷火效果) delay = 60 # 控制分级图片切换的频率(延时参数) running = True pygame.mixer.music.play(-1) # 循环播放背景音乐 me = myplane.MyPlane(bg_size) # 生成我方飞机 score = 0 # 统计用户得分 paused = False # 标志是否暂停游戏 pause_nor_image = pygame.image.load("image/game_pause_nor.png") # 加载暂停相关按钮 pause_pressed_image = pygame.image.load("image/game_pause_pressed.png") resume_nor_image = pygame.image.load("image/game_resume_nor.png") resume_pressed_image = pygame.image.load("image/game_resume_pressed.png") paused_rect = pause_nor_image.get_rect() paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10 # 设置暂停按钮位置 paused_image = pause_nor_image # 设置默认显示的暂停按钮 score_font = pygame.font.SysFont("arial", 48) # 定义分数字体 color_black = (0, 0, 0) color_green = (0, 255, 0) color_red = (255, 0, 0) color_white = (255, 255, 255) bomb_image = pygame.image.load("image/bomb.png") # 加载全屏炸弹图标 bomb_rect = bomb_image.get_rect() bomb_front = score_font bomb_num = 3 # 初始为三个炸弹 level = 1 # 游戏难度级别 life_image = pygame.image.load("image/life.png").convert() life_rect = life_image.get_rect() life_num = 3 # 一共有三条命 invincible_time = USEREVENT + 2 # 接触我方飞机无敌时间定时器 flag_recorded = False # 是否已经打开记录文件标志位 gameover_image = pygame.image.load("image/game_over.png") # 游戏结束背景图片 gameover_rect = gameover_image.get_rect() # ====================生成普通子弹==================== bullet1 = [] bullet1_index = 0 bullet1_num = 6 # 定义子弹实例化个数 for i in range(bullet1_num): bullet1.append(bullet.Bullet1(me.rect.midtop)) # ====================生成超级子弹==================== double_bullet_timer = USEREVENT + 1 # 超级子弹持续时间定时器 is_double_bullet = False # 是否使用超级子弹标志位 bullet2 = [] bullet2_index = 0 bullet2_num = 10 # 定义子弹实例化个数 for i in range(bullet2_num//2): bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery))) bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery))) # ====================实例化敌方飞机==================== enemies = pygame.sprite.Group() # 生成敌方飞机组 small_enemies = pygame.sprite.Group() # 敌方小型飞机组 add_small_enemies(small_enemies, enemies, 1) # 生成若干敌方小型飞机 mid_enemies = pygame.sprite.Group() # 敌方小型飞机组 add_mid_enemies(mid_enemies, enemies, 1) # 生成若干敌方中型飞机 big_enemies = pygame.sprite.Group() # 敌方小型飞机组 add_big_enemies(big_enemies, enemies, 1) # 生成若干敌方大型飞机 # ====================实例化补给包==================== bullet_supply = supply.BulletSupply(bg_size) bomb_supply = supply.BombSupply(bg_size) supply_timer = USEREVENT # 补给包发放定时器 pygame.time.set_timer(supply_timer, 10 * 1000) # 定义每30秒发放一次补给包 # ====================飞机损毁图像索引==================== e1_destroy_index = 0 e2_destroy_index = 0 e3_destroy_index = 0 me_destroy_index = 0 # =============================================================================== # 主要功能:主循环,响应用户鼠标按键以及键盘事件 # 算法流程: # 注意事项: # =============================================================================== while running: screen.blit(background, (0, 0)) # 将背景图片打印到内存的屏幕上 score_text = score_font.render("Score : %s" % str(score), True, color_white) screen.blit(score_text, (10, 5)) # ====================定义难度递进操作==================== if level == 1 and score > 5000: # 如果达到第二难度等级,则增加3架小型敌机,2架中型敌机,1架大型敌机,并提升小型敌机速度 level = 2 level_up_sound.play() add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) inc_speed(small_enemies, 1) elif level == 2 and score > 30000: # 如果达到第三难度等级 level = 3 level_up_sound.play() add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) inc_speed(small_enemies, 1) inc_speed(mid_enemies, 1) elif level == 3 and score > 60000: # 如果达到第四难度等级 level = 4 level_up_sound.play() add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) inc_speed(small_enemies, 1) inc_speed(mid_enemies, 1) inc_speed(big_enemies, 1) # ====================检测用户的退出及暂停操作==================== for event in pygame.event.get(): # 响应用户的偶然操作 if event.type == QUIT: # 如果用户按下屏幕上的关闭按钮,触发QUIT事件,程序退出 pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: button_down_sound.play() if event.button == 1 and paused_rect.collidepoint(event.pos): # 如果检测到用户在指定按钮区域按下鼠标左键 paused = not paused if paused: # r如果当前的状态是暂停 paused_image = resume_pressed_image pygame.time.set_timer(supply_timer, 0) # 关闭补给机制以及所有音效 pygame.mixer.music.pause() pygame.mixer.pause() else: paused_image = pause_pressed_image pygame.time.set_timer(supply_timer, 30 * 1000) # 开启补给机制以及所有音效 pygame.mixer.music.unpause() pygame.mixer.unpause() elif event.type == MOUSEMOTION: if paused_rect.collidepoint(event.pos): # 如果鼠标悬停在按钮区域 if paused: # r如果当前的状态是暂停 paused_image = resume_pressed_image else: paused_image = pause_pressed_image else: if paused: paused_image = resume_nor_image else: paused_image = pause_nor_image elif event.type == KEYDOWN: if event.key == K_SPACE: # 如果检测到用户按下空格键 if bomb_num: # 如果炸弹数量大于零,则引爆一颗超级炸弹 bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0: # 屏幕上的所有敌机均销毁 each.active = False elif event.type == supply_timer: # 响应补给发放的事件消息 if choice([True, False]): bomb_supply.reset() else: bullet_supply.reset() elif event.type == double_bullet_timer: is_double_bullet = False pygame.time.set_timer(double_bullet_timer, 0) elif event.type == invincible_time: # 如果无敌时间已过 me.invincible = False pygame.time.set_timer(invincible_time, 0) screen.blit(paused_image, paused_rect) if life_num and (not paused): # 如果游戏未被暂停,正常运行 # ====================绘制全屏炸弹数量和剩余生命数量==================== bomb_text = bomb_front.render("× %d" % bomb_num, True, color_black) bomb_text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit(bomb_text, (20 + bomb_rect.width, height - 10 - bomb_text_rect.height)) if life_num: for i in range(life_num): screen.blit(life_image, (width - 10 - (i + 1) * life_rect.width, height - 10 - life_rect.height)) # ====================检测用户的键盘操作==================== key_pressed = pygame.key.get_pressed() # 获得用户所有的键盘输入序列 if key_pressed[K_w] or key_pressed[K_UP]: # 如果用户通过键盘发出“向上”的指令,其他类似 me.move_up() if key_pressed[K_s] or key_pressed[K_DOWN]: me.move_down() if key_pressed[K_a] or key_pressed[K_LEFT]: me.move_left() if key_pressed[K_d] or key_pressed[K_RIGHT]: me.move_right() if not (delay % 10): # 每十帧发射一颗移动的子弹 bullet_sound.play() if not is_double_bullet: # 如果当前是普通子弹状态 bullets = bullet1 bullets[bullet1_index].reset(me.rect.midtop) bullet1_index = (bullet1_index + 1) % bullet1_num else: # 如果当前是超级子弹状态 bullets = bullet2 bullets[bullet2_index].reset((me.rect.centerx - 33, me.rect.centery)) bullets[bullet2_index + 1].reset((me.rect.centerx + 30, me.rect.centery)) bullet2_index = (bullet2_index + 2) % bullet2_num # ====================绘制补给并检测玩家是否获得==================== if bomb_supply.active: # 如果是超级炸弹补给包 bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, me): # 如果玩家获得超级炸弹补给包 get_bomb_sound.play() if bomb_num < 3: bomb_num += 1 bomb_supply.active = False if bullet_supply.active: # 如果是超级子弹补给包 bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, me): get_bullet_sound.play() is_double_bullet = True pygame.time.set_timer(double_bullet_timer, 18 * 1000) bullet_supply.active = False # ====================子弹与敌机的碰撞检测==================== for b in bullets: if b.active: # 只有激活的子弹才可能击中敌机 b.move() # 子弹移动 screen.blit(b.image, b.rect) enemies_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask) if enemies_hit: # 如果子弹击中飞机 b.active = False # 子弹损毁 for e in enemies_hit: if e in big_enemies or e in mid_enemies: e.energy -= 1 e.hit = True # 表示飞机已经被击中 if e.energy == 0: e.active = False # 大中型敌机损毁 else: e.active = False # 小型敌机损毁 # ====================我方飞机碰撞检测==================== enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask) if enemies_down and not me.invincible: # 如果碰撞检测返回的列表非空,则说明已发生碰撞,若此时我方飞机处于无敌状态 me.active = False for e in enemies_down: e.active = False # 敌机损毁 # ====================绘制我方飞机,设置两种飞机交替绘制,以实现动态喷气效果==================== if delay == 0: delay = 60 delay -= 1 if not delay % 3: switch_image = not switch_image if me.active: if switch_image: screen.blit(me.image1, me.rect) # 绘制我方飞机的两种不同的形式 else: screen.blit(me.image2, me.rect) else: if not (delay % 3): screen.blit(me.destroy_images[me_destroy_index], me.rect) # 绘制我方飞机损毁画面 me_destroy_index = (me_destroy_index + 1) % 4 if me_destroy_index == 0: me_down_sound.play() life_num -= 1 me.reset() # 我方飞机重生并开始无敌时间计时 pygame.time.set_timer(invincible_time, 3 * 1000) # ====================绘制敌方飞机,由大到小进行绘制,避免速度快的小飞机被覆盖==================== for each in big_enemies: # 绘制大型敌机并自动移动 if each.active: # 如果飞机正常存在 each.move() # 绘制大型敌机 if not each.hit: # 如果飞机未被击中 if switch_image: screen.blit(each.image1, each.rect) # 绘制大型敌机的两种不同的形式 else: screen.blit(each.image2, each.rect) else: screen.blit(each.image_hit, each.rect) each.hit = False # ====================绘制血槽==================== pygame.draw.line(screen, color_black, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) energy_remain = each.energy / enemy.BigEnemy.energy if energy_remain > 0.2: # 如果血量大约百分之二十则为绿色,否则为红色 energy_color = color_green else: energy_color = color_red pygame.draw.line(screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) if each.rect.bottom == -50: big_enemy_flying_sound.play(-1) # 播放大型飞机的音效(循环播放) else: # 如果飞机已撞毁 big_enemy_flying_sound.stop() # 出场音效停止 if e3_destroy_index == 0: enemy3_down_sound.play() # 播放飞机撞毁音效 if not (delay % 3): # 每三帧播放一张损毁图片 screen.blit(each.destroy_images[e3_destroy_index], each.rect) e3_destroy_index = (e3_destroy_index + 1) % 6 # 大型敌机有六张损毁图片 if e3_destroy_index == 0: # 如果损毁图片播放完毕,则重置飞机属性 score += 6000 # 击毁一架大型敌机得6000分 each.reset() for each in mid_enemies: # 绘制中型敌机并自动移动 if each.active: each.move() # 绘制中型敌机 if not each.hit: screen.blit(each.image, each.rect) else: screen.blit(each.image_hit, each.rect) each.hit = False # ====================绘制血槽==================== pygame.draw.line(screen, color_black, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) energy_remain = each.energy / enemy.MidEnemy.energy if energy_remain > 0.2: # 如果血量大约百分之二十则为绿色,否则为红色 energy_color = color_green else: energy_color = color_red pygame.draw.line(screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) else: if e2_destroy_index == 0: enemy2_down_sound.play() # 播放损毁音效 if not (delay % 3): screen.blit(each.destroy_images[e2_destroy_index], each.rect) # 绘制损毁画面 e2_destroy_index = (e2_destroy_index + 1) % 4 if e2_destroy_index == 0: score += 2000 # 击毁一架中型飞机得2000分 each.reset() for each in small_enemies: # 绘制小型敌机并自动移动 if each.active: each.move() # 绘制小型敌机 screen.blit(each.image, each.rect) else: if e1_destroy_index == 0: enemy1_down_sound.play() # 敌机损毁音效 if not (delay % 3): screen.blit(each.destroy_images[e1_destroy_index], each.rect) # 播放损毁画面 e1_destroy_index = (e1_destroy_index + 1) % 4 if e1_destroy_index == 0: score += 500 # 击毁一架小型飞机得500分 each.reset() elif life_num == 0: # 生命值为零,绘制游戏结束画面 screen.blit(gameover_image, gameover_rect) pygame.mixer.music.stop() # 关闭背景音乐 pygame.mixer.stop() # 关闭所有音效 pygame.time.set_timer(supply_timer, 0) # 关闭补给机制 if not flag_recorded: # 读取历史最高分 flag_recorded = True with open("score_record.txt", "r") as f: record_score = int(f.read()) if score > record_score: # 如果玩家得分大于历史最高分,则将当前分数存档 with open("score_record.txt", "w") as f: f.write(str(score)) record_score_text = score_font.render("%d" % record_score, True, color_white) screen.blit(record_score_text, (150, 25)) game_over_score_text = score_font.render("%d" % score, True, color_white) screen.blit(game_over_score_text, (180, 370)) pygame.display.flip() # 将内存中绘制好的屏幕刷新到设备屏幕上 clock.tick(60) # 设置帧数为60
def main(): clock = pygame.time.Clock() switch_image = False delay = 60 running = True pygame.mixer.music.play(-1) me = myPlane.MyPlane(bg_size) score = 0 paused = False pause_nor_image = pygame.image.load("resources/image/game_pause_nor.png") pause_pressed_image = pygame.image.load("resources/image/game_pause_pressed.png") resume_nor_image = pygame.image.load("resources/image/game_resume_nor.png") resume_pressed_image = pygame.image.load("resources/image/game_resume_pressed.png") paused_rect = pause_nor_image.get_rect() paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10 paused_image = pause_nor_image score_font = pygame.font.SysFont("Helvetica", 50) color_black = (0, 0, 0) color_green = (0, 255, 0) color_red = (255, 0, 0) color_white = (255, 255, 255) bomb_image = pygame.image.load("resources/image/bomb.png") bomb_rect = bomb_image.get_rect() bomb_front = pygame.font.SysFont("Helvetica", 50) bomb_num = 3 level = 1 life_image = pygame.image.load("resources/image/enemy1.png") life_rect = life_image.get_rect() life_num = 3 invincible_time = USEREVENT + 2 flag_recorded = False gameover_image = pygame.image.load("resources/image/game_over.png") gameover_rect = gameover_image.get_rect() bullet1 = [] bullet1_index = 0 bullet1_num = 6 for i in range(bullet1_num): bullet1.append(bullet.Bullet1(me.rect.midtop)) double_bullet_timer = USEREVENT + 1 is_double_bullet = False bullet2 = [] bullet2_index = 0 bullet2_num = 10 for i in range(bullet2_num//2): bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery))) bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery))) enemies = pygame.sprite.Group() small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, 1) mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, 1) big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 1) bullet_supply = supply.BulletSupply(bg_size) bomb_supply = supply.BombSupply(bg_size) supply_timer = USEREVENT pygame.time.set_timer(supply_timer, 10 * 1000) e1_destroy_index = 0 e2_destroy_index = 0 e3_destroy_index = 0 me_destroy_index = 0 while running: screen.blit(background, (0, 0)) score_text = score_font.render("Score : %s" % str(score), True, color_white) screen.blit(score_text, (10, 5)) if level == 1 and score > 5000: level = 2 level_up_sound.play() add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) inc_speed(small_enemies, 1) elif level == 2 and score > 30000: level = 3 level_up_sound.play() pygame.time.set_timer(supply_timer, 20 * 1000) add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) inc_speed(small_enemies, 1) inc_speed(mid_enemies, 1) elif level == 3 and score > 60000: level = 4 level_up_sound.play() pygame.time.set_timer(supply_timer, 30 * 1000) add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) inc_speed(small_enemies, 1) inc_speed(mid_enemies, 1) inc_speed(big_enemies, 1) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: button_down_sound.play() if event.button == 1 and paused_rect.collidepoint(event.pos): paused = not paused if paused: paused_image = resume_pressed_image pygame.time.set_timer(supply_timer, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: paused_image = pause_pressed_image pygame.time.set_timer(supply_timer, 30 * 1000) pygame.mixer.music.unpause() pygame.mixer.unpause() elif event.type == MOUSEMOTION: if paused_rect.collidepoint(event.pos): if paused: paused_image = resume_pressed_image else: paused_image = pause_pressed_image else: if paused: paused_image = resume_nor_image else: paused_image = pause_nor_image elif event.type == KEYDOWN: if event.key == K_SPACE: if bomb_num: bomb_num -= 1 bomb_sound.play() for each in enemies: if each.rect.bottom > 0: each.active = False elif event.type == supply_timer: if choice([True, False]): bomb_supply.reset() else: bullet_supply.reset() elif event.type == double_bullet_timer: is_double_bullet = False pygame.time.set_timer(double_bullet_timer, 0) elif event.type == invincible_time: me.invincible = False pygame.time.set_timer(invincible_time, 0) screen.blit(paused_image, paused_rect) if life_num and (not paused): bomb_text = bomb_front.render("X {}".format(bomb_num), True, color_black) bomb_text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) screen.blit(bomb_text, (20 + bomb_rect.width, height - 10 - bomb_text_rect.height)) if life_num: for i in range(life_num): screen.blit(life_image, (width - 10 - (i + 1) * life_rect.width, height - 10 - life_rect.height)) key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: me.move_up() if key_pressed[K_s] or key_pressed[K_DOWN]: me.move_down() if key_pressed[K_a] or key_pressed[K_LEFT]: me.move_left() if key_pressed[K_d] or key_pressed[K_RIGHT]: me.move_right() if not (delay % 10): bullet_sound.play() if not is_double_bullet: bullets = bullet1 bullets[bullet1_index].reset(me.rect.midtop) bullet1_index = (bullet1_index + 1) % bullet1_num else: bullets = bullet2 bullets[bullet2_index].reset((me.rect.centerx - 33, me.rect.centery)) bullets[bullet2_index + 1].reset((me.rect.centerx + 30, me.rect.centery)) bullet2_index = (bullet2_index + 2) % bullet2_num if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, me): get_bomb_sound.play() if bomb_num < 3: bomb_num += 1 bomb_supply.active = False if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, me): get_bullet_sound.play() is_double_bullet = True pygame.time.set_timer(double_bullet_timer, 18 * 1000) bullet_supply.active = False for b in bullets: if b.active: b.move() screen.blit(b.image, b.rect) enemies_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask) if enemies_hit: b.active = False for e in enemies_hit: if e in big_enemies or e in mid_enemies: e.energy -= 1 e.hit = True if e.energy == 0: e.active = False else: e.active = False enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask) if enemies_down and not me.invincible: me.active = False for e in enemies_down: e.active = False if delay == 0: delay = 60 delay -= 1 if not delay % 3: switch_image = not switch_image if me.active: if switch_image: screen.blit(me.image1, me.rect) else: screen.blit(me.image2, me.rect) else: if not (delay % 3): screen.blit(me.destroy_images[me_destroy_index], me.rect) me_destroy_index = (me_destroy_index + 1) % 4 if me_destroy_index == 0: me_down_sound.play() life_num -= 1 me.reset() pygame.time.set_timer(invincible_time, 3 * 1000) for each in big_enemies: if each.active: each.move() if not each.hit: if switch_image: screen.blit(each.image1, each.rect) else: screen.blit(each.image2, each.rect) else: screen.blit(each.image_hit, each.rect) each.hit = False pygame.draw.line(screen, color_black, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) energy_remain = each.energy / enemy.BigEnemy.energy if energy_remain > 0.2: energy_color = color_green else: energy_color = color_red pygame.draw.line(screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) if each.rect.bottom == -50: big_enemy_flying_sound.play(-1) else: big_enemy_flying_sound.stop() if e3_destroy_index == 0: enemy3_down_sound.play() if not (delay % 3): screen.blit(each.destroy_images[e3_destroy_index], each.rect) e3_destroy_index = (e3_destroy_index + 1) % 6 if e3_destroy_index == 0: score += 6000 each.reset() for each in mid_enemies: if each.active: each.move() if not each.hit: screen.blit(each.image, each.rect) else: screen.blit(each.image_hit, each.rect) each.hit = False pygame.draw.line(screen, color_black, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) energy_remain = each.energy / enemy.MidEnemy.energy if energy_remain > 0.2: energy_color = color_green else: energy_color = color_red pygame.draw.line(screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) else: if e2_destroy_index == 0: enemy2_down_sound.play() if not (delay % 3): screen.blit(each.destroy_images[e2_destroy_index], each.rect) e2_destroy_index = (e2_destroy_index + 1) % 4 if e2_destroy_index == 0: score += 2000 each.reset() for each in small_enemies: if each.active: each.move() screen.blit(each.image, each.rect) else: if e1_destroy_index == 0: enemy1_down_sound.play() if not (delay % 3): screen.blit(each.destroy_images[e1_destroy_index], each.rect) e1_destroy_index = (e1_destroy_index + 1) % 4 if e1_destroy_index == 0: score += 500 each.reset() elif life_num == 0: screen.blit(gameover_image, gameover_rect) pygame.mixer.music.stop() pygame.mixer.stop() pygame.time.set_timer(supply_timer, 0) if not flag_recorded: flag_recorded = True with open("score_record.txt", "r") as f: record_score = int(f.read()) if score > record_score: with open("score_record.txt", "w") as f: f.write(str(score)) record_score_text = score_font.render("%d" % record_score, True, color_white) screen.blit(record_score_text, (150, 25)) game_over_score_text = score_font.render("%d" % score, True, color_white) screen.blit(game_over_score_text, (180, 370)) pygame.display.flip() clock.tick(60)