def main(): pygame.mixer.music.play(-1) # 生成我方飞机 me = myplane.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, 8) # 生成敌方大型飞机 big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 4) # 生成普通子弹 bullet1 = [] bullet1_index = 0 BULLET1_NUM = 4 for i in range(BULLET1_NUM): bullet1.append(bullet.Bullet1((me.rect.centerx - 16, me.rect.centery))) # 生成超级子弹 bullet2 = [] bullet2_index = 0 BULLET2_NUM = 8 for i in range(BULLET2_NUM // 2): bullet2.append(bullet.Bullet2((me.rect.centerx - 56, me.rect.centery))) bullet2.append(bullet.Bullet2((me.rect.centerx + 8, me.rect.centery))) #生成敌机子弹 bullet3 = [] bullet3_index = 0 BULLET3_NUM = 8 clock = pygame.time.Clock() # 中弹图片索引 e1_destroy_index = 0 e2_destroy_index = 0 e3_destroy_index = 0 me_destroy_index = 0 #生成护盾 protection_cover = pygame.image.load( "images/Protection_cover.png").convert_alpha() # 统计得分 score = 0 score_font = pygame.font.Font("font/font.ttf", 36) # 标志是否暂停游戏 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() 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("images/bomb.png").convert_alpha() bomb_rect = bomb_image.get_rect() bomb_font = pygame.font.Font("font/font.ttf", 48) bomb_num = 3 # 每20秒发放一个补给包 bullet_supply = supply.Bullet_Supply(bg_size) bomb_supply = supply.Bomb_Supply(bg_size) shield_supply = supply.Shield_Supply(bg_size) life_supply = supply.Life_Supply(bg_size) SUPPLY_TIME = pygame.USEREVENT pygame.time.set_timer(SUPPLY_TIME, 20 * 1000) # 超级子弹定时器 DOUBLE_BULLET_TIME = pygame.USEREVENT + 1 # 标志是否使用超级子弹 is_double_bullet = False # 解除我方无敌状态定时器 INVINCIBLE_TIME = pygame.USEREVENT + 2 # 生命数量 life_image = pygame.image.load("images/life.png").convert_alpha() life_rect = life_image.get_rect() life_num = 3 # 用于阻止重复打开记录文件 recorded = False # 游戏结束画面 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() # 用于切换图片 switch_image = True # 用于延迟 delay = 100 running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.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, 20 * 1000) pygame.mixer.music.unpause() pygame.mixer.unpause() elif event.type == pygame.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 == pygame.KEYDOWN: if event.key == pygame.K_SPACE and not paused: 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() x = random.randint(0, 3) if x == 0: bomb_supply.reset() elif x == 1: bullet_supply.reset() elif x == 2: shield_supply.reset() else: life_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 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) screen.blit(background, (0, 0)) if life_num >= 0 and not paused: # 检测用户的键盘操作 key_pressed = pygame.key.get_pressed() if key_pressed[pygame.K_w] or key_pressed[pygame.K_UP]: me.moveUp() if key_pressed[pygame.K_s] or key_pressed[pygame.K_DOWN]: me.moveDown() if key_pressed[pygame.K_a] or key_pressed[pygame.K_LEFT]: me.moveLeft() if key_pressed[pygame.K_d] or key_pressed[pygame.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_double_bullet = True pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000) bullet_supply.active = False # 绘制护盾补给并检测是否获得 if shield_supply.active: shield_supply.move() screen.blit(shield_supply.image, shield_supply.rect) if pygame.sprite.collide_mask(shield_supply, me): get_bullet_sound.play() pygame.time.set_timer(INVINCIBLE_TIME, 15 * 1000) me.invincible = True shield_supply.active = False # 绘制生命补给并检测是否获得 if life_supply.active: life_supply.move() screen.blit(life_supply.image, life_supply.rect) if pygame.sprite.collide_mask(life_supply, me): get_bomb_sound.play() if life_num < 3: life_num += 1 life_supply.active = False # 发射子弹 if not (delay % 10): bullet_sound.play() if is_double_bullet: bullets = bullet2 bullets[bullet2_index].reset( (me.rect.centerx - 56, me.rect.centery)) bullets[bullet2_index + 1].reset( (me.rect.centerx + 8, me.rect.centery)) bullet2_index = (bullet2_index + 2) % BULLET2_NUM else: bullets = bullet1 bullets[bullet1_index].reset( (me.rect.centerx - 16, me.rect.centery)) 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 if is_double_bullet: e.energy -= 2 else: e.energy -= 1 if e.energy <= 0: e.active = False else: e.active = False # 检测子弹是否击中我机 for b in bullet3: if b.active: b.move() screen.blit(b.image, b.rect) me_hit = pygame.sprite.collide_mask(b, me) if me_hit and not me.invincible: me.active = False b.active = False # 绘制大型敌机 for each in big_enemies: if each.active: each.move() if not (delay % 10) and each.rect.bottom > 0: for i in range(BULLET3_NUM // 2): bullet3.append( bullet.Bullet3((each.rect.centerx - 56, each.rect.centery + each.rect.height - 170))) bullet3.append( bullet.Bullet3( (each.rect.centerx + 8, each.rect.centery + each.rect.height - 170))) bullet3[bullet3_index].reset( (each.rect.centerx - 56, each.rect.centery + each.rect.height - 170)) bullet3[bullet3_index + 1].reset( (each.rect.centerx + 8, each.rect.centery + each.rect.height - 170)) bullet3_index = (bullet3_index + 2) % BULLET3_NUM 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 += 15000 each.reset() # 绘制中型敌机: 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) # 绘制血槽 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 me.invincible: screen.blit(protection_cover, (me.rect.left - 5, me.rect.top)) 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(" 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)) # 绘制剩余生命数量 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)) # 绘制暂停按钮 screen.blit(paused_image, paused_rect) # 绘制游戏结束画面 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)) gameover_text1 = gameover_font.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 = gameover_font.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) 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) # 检测用户的鼠标操作 # 如果用户按下鼠标左键 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 gameover_rect.left < pos[0] < gameover_rect.right and \ gameover_rect.top < pos[1] < gameover_rect.bottom: # 退出游戏 pygame.quit() sys.exit() else: # 绘制暂停按钮 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(): # here we creat background background1 = background.Background(size) background2 = background.background(size) # here we creat myplane my_plane = pygame.sprite.Group() myplane1 = myplane.Myplane(size) my_plane.add(myplane1) # here we creat the enemy planes enemies = pygame.sprite.Group() enemy3 = pygame.sprite.Group() enemy2 = pygame.sprite.Group() boss = pygame.sprite.Group() e21 = enemy.Enemy2(size) e22 = enemy.Enemy2(size) e23 = enemy.Enemy2(size) e24 = enemy.Enemy2(size) e25 = enemy.Enemy2(size) boss1 = enemy.Enemy8(size) enemy2.add(e21) enemy2.add(e22) enemy2.add(e23) enemy2.add(e24) enemy2.add(e25) enemies.add(e21) enemies.add(e22) enemies.add(e23) enemies.add(e24) enemies.add(e25) boss.add(boss1) e3 = enemy.Enemy3(size) enemy3.add(e3) enemy1 = pygame.sprite.Group() add_enemy1(enemy1, enemies, 3) enemy4 = pygame.sprite.Group() add_enemy4(enemy4, enemies, 2) enemy5 = pygame.sprite.Group() enemy6 = pygame.sprite.Group() enemy7 = pygame.sprite.Group() add_enemy7(enemy7, enemies, 1) # here we creat the bullets bullet1 = [] bullet1_index = 0 bullet1_number = 80 for i in range(bullet1_number // 2): bullet1.append( bullet.Bullet1( (myplane1.rect.centerx - 13, myplane1.rect.centery))) bullet1.append( bullet.Bullet1( (myplane1.rect.centerx + 13, myplane1.rect.centery))) # here we creat the super bullet bullet2 = [] bullet2_index = 0 bullet2_number = 80 for i in range(bullet2_number // 2): bullet2.append( bullet.Bullet2( (myplane1.rect.centerx - 13, myplane1.rect.centery))) bullet2.append( bullet.Bullet2( (myplane1.rect.centerx + 13, myplane1.rect.centery))) # here we creat the super bullet bullet3 = [] bullet3_index = 0 bullet3_number = 40 for i in range(bullet3_number): bullet3.append( bullet.Bullet3( (myplane1.rect.centerx - 23, myplane1.rect.centery))) # here we creat the super bullet bullet4 = [] bullet4_index = 0 bullet4_number = 40 for i in range(bullet4_number): bullet4.append( bullet.Bullet4( (myplane1.rect.centerx + 23, myplane1.rect.centery))) bullet6 = [] bullet6_index = 0 bullet6_number = 5000 for i in range(bullet6_number // 5): bullet6.append( bullet.Bullet6((boss1.rect.centerx - 300, boss1.rect.centery))) bullet6.append( bullet.Bullet6((boss1.rect.centerx - 100, boss1.rect.centery))) bullet6.append( bullet.Bullet6((boss1.rect.centerx + 100, boss1.rect.centery))) bullet6.append( bullet.Bullet6((boss1.rect.centerx + 300, boss1.rect.centery))) # here we creat the enemy bullet bullet5 = bullet.Bullet5(size) b5 = pygame.sprite.Group() b5.add(bullet5) bullet51 = bullet.Bullet6(size) b51 = pygame.sprite.Group() b51.add(bullet51) bullet52 = bullet.Bullet6(size) b52 = pygame.sprite.Group() b52.add(bullet52) bullet53 = bullet.Bullet6(size) b53 = pygame.sprite.Group() b53.add(bullet53) bullet54 = bullet.Bullet6(size) b54 = pygame.sprite.Group() b54.add(bullet54) bullet55 = bullet.Bullet6(size) b55 = pygame.sprite.Group() b55.add(bullet55) # the index of plane when it is destoried e1_destroy_index = 0 e2_destroy_index = 0 en3_destroy_index = 0 e4_destroy_index = 0 e5_destroy_index = 0 e6_destroy_index = 0 e7_destroy_index = 0 myplane1_destroy_index = 0 boss_destroy_index = 0 # here we add the score to the game score = 0 score_font = pygame.font.Font("font/font.ttf.ttf", 36) #here we set the stop condtion to the game paused = False pause_nor_image = pygame.image.load("images/22.png").convert_alpha() pause_pressed_image = pygame.image.load("images/23.png").convert_alpha() resume_nor_image = pygame.image.load("images/21.png").convert_alpha() resume_pressed_image = pygame.image.load("images/24.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 # here we set the difficulty of the game level = 1 # here we set the bomb skills bomb_image = pygame.image.load("images/25.png").convert_alpha() bomb_rect = bomb_image.get_rect() bomb_font = pygame.font.Font("font/font.ttf.ttf", 48) bomb_num = 3 # here we set record time recorded = False # here we set the ending picture gameover_font = pygame.font.Font("font/font.ttf.ttf", 48) again_image = pygame.image.load("images/29.png").convert_alpha() again_rect = again_image.get_rect() gameover_image = pygame.image.load("images/30.png").convert_alpha() gameover_rect = gameover_image.get_rect() # here we set the supply bullet_supply = supply.Bullet_supply(size) bomb_supply = supply.Bomb_supply(size) supply_time = USEREVENT pygame.time.set_timer(supply_time, 15 * 1000) # here we set the timing of super bullet super_bullet_time = USEREVENT + 1 # here we add the timing of myplane's invincibe invincible_time = USEREVENT + 2 # here we set condition of the super bullet is_super_bullet = False # here we set the lives of my planes life_image = pygame.image.load("images/28.png").convert_alpha() life_rect = life_image.get_rect() life_num = 3 # here we set the delay to make the picture change smoothly delay = 120 # here we set the state of running to check if we need to end the game running = True clock = pygame.time.Clock() # here we start the game while running: print(delay) for event in pygame.event.get(): # here we quit the game and exit the system 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) else: pygame.time.set_timer(supply_time, 15 * 1000) 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 # here we set the function of the bomb elif event.type == KEYDOWN: if event.key == K_SPACE: if bomb_num: bomb_num -= 1 for each in enemies: if each.rect.bottom > 0: each.active = False if level == 7: boss1.energy -= 100 if boss1.energy < 0: boss1.active = False # here we set the supply type elif event.type == supply_time: 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 == invincible_time: myplane1.invincible = False pygame.time.set_timer(invincible_time, 0) # here we change the levels if level == 1 and score > 100: level = 2 # add more enemy planes to increase the difficulty level add_enemy1(enemy1, enemies, 1) add_enemy4(enemy4, enemies, 1) # increase the speed of the small enemy plane inc_speed(enemy1, 1) elif level == 2 and score > 300: level = 3 # add more enemy planes to increase the difficulty level add_enemy1(enemy1, enemies, 1) add_enemy4(enemy4, enemies, 1) add_enemy5(enemy5, enemies, 1) add_enemy6(enemy6, enemies, 1) # increase the speed of the small enemy plane inc_speed(enemy1, 1) elif level == 3 and score > 800: level = 4 # add more enemy planes to increase the difficulty level add_enemy1(enemy1, enemies, 1) add_enemy5(enemy5, enemies, 1) add_enemy6(enemy6, enemies, 1) # increase the speed of the small enemy plane elif level == 4 and score > 1500: level = 5 # add more enemy planes to increase the difficulty level add_enemy1(enemy1, enemies, 1) add_enemy4(enemy4, enemies, 1) # increase the speed of the small enemy plane inc_speed(enemy4, 1) elif level == 5 and score > 2500: level = 6 # add more enemy planes to increase the difficulty level add_enemy1(enemy1, enemies, 2) add_enemy4(enemy4, enemies, 1) add_enemy5(enemy5, enemies, 1) add_enemy6(enemy6, enemies, 1) # increase the speed of the small enemy plane inc_speed(enemy1, 1) elif level == 6 and score > 4000: score = 4000 level = 7 # delete all the enemy planes e3.active = False e3.reset() for each in enemies: each.active = False each.reset() boss1.active = True if score == 4000: score += 100 delay = 120 # here we draw the background picture if background1.active: background1.move() screen.blit(background1.image, background1.rect) if background2.active: background2.move() screen.blit(background2.image, background2.rect) if life_num and not paused: # here we check the keyboard of user key_pressed = pygame.key.get_pressed() if key_pressed[K_w]: myplane1.moveUp() if key_pressed[K_s]: myplane1.moveDown() if key_pressed[K_a]: myplane1.moveLeft() if key_pressed[K_d]: myplane1.moveRight() # here we draw the bomb and indicate if the player get it if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, myplane1): if bomb_num < 3: bomb_num += 1 bomb_supply.active = False # here we draw the bullet supply and indicate if the player get it if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(bullet_supply, myplane1): # creat and shoot the super bullet is_super_bullet = True pygame.time.set_timer(super_bullet_time, 8 * 1000) bullet_supply.active = False # here we check that if the user's plane is touched by the enemies and their bullets enemies_down = pygame.sprite.spritecollide( myplane1, enemies, False, pygame.sprite.collide_mask) enemy3_down = pygame.sprite.spritecollide( myplane1, enemy3, False, pygame.sprite.collide_mask) enemy2_down = pygame.sprite.spritecollide( myplane1, enemy2, False, pygame.sprite.collide_mask) b5_down = pygame.sprite.spritecollide(myplane1, b5, False, pygame.sprite.collide_mask) b51_down = pygame.sprite.spritecollide(myplane1, b51, False, pygame.sprite.collide_mask) b52_down = pygame.sprite.spritecollide(myplane1, b52, False, pygame.sprite.collide_mask) b53_down = pygame.sprite.spritecollide(myplane1, b53, False, pygame.sprite.collide_mask) b54_down = pygame.sprite.spritecollide(myplane1, b54, False, pygame.sprite.collide_mask) b55_down = pygame.sprite.spritecollide(myplane1, b55, False, pygame.sprite.collide_mask) if enemies_down and not myplane1.invincible: myplane1.invincible = True pygame.time.set_timer(invincible_time, 1 * 1000) myplane1.energy -= 1 if myplane1.energy == 0: myplane1.active = False for e in enemies_down: e.active = False if enemy3_down and not myplane1.invincible: myplane1.invincible = True pygame.time.set_timer(invincible_time, 1 * 1000) myplane1.energy -= 1 if myplane1.energy == 0: myplane1.active = False e3.active = False if enemy2_down and not myplane1.invincible: myplane1.invincible = True pygame.time.set_timer(invincible_time, 1 * 1000) myplane1.energy -= 1 if myplane1.energy == 0: myplane1.active = False for m in enemy2_down: m.active = False if b5_down and not myplane1.invincible: myplane1.energy -= 1 if myplane1.energy == 0: myplane1.active = False bullet5.active = False bullet5.reset((e3.rect.centerx, e3.rect.bottom)) if b51_down and not myplane1.invincible: myplane1.energy -= 1 if myplane1.energy == 0: myplane1.active = False bullet51.active = False bullet51.reset((e21.rect.centerx, e21.rect.bottom)) if b52_down and not myplane1.invincible: myplane1.energy -= 1 if myplane1.energy == 0: myplane1.active = False bullet52.active = False bullet52.reset((e22.rect.centerx, e22.rect.bottom)) if b53_down and not myplane1.invincible: myplane1.energy -= 1 if myplane1.energy == 0: myplane1.active = False bullet53.active = False bullet53.reset((e23.rect.centerx, e23.rect.bottom)) if b54_down and not myplane1.invincible: myplane1.energy -= 1 if myplane1.energy == 0: myplane1.active = False bullet54.active = False bullet54.reset((e24.rect.centerx, e24.rect.bottom)) if b55_down and not myplane1.invincible: myplane1.energy -= 1 if myplane1.energy == 0: myplane1.active = False bullet55.active = False bullet55.reset((e25.rect.centerx, e25.rect.bottom)) # here we draw the user's plane if myplane1.active: screen.blit(myplane1.image, myplane1.rect) # here we draw the total blood of my plane pygame.draw.line(screen, BLACK, \ (myplane1.rect.left, myplane1.rect.bottom + 5),\ (myplane1.rect.right, myplane1.rect.bottom + 5),\ 2) # when the energy is bigger than 20%, it will be green. else, it will be red energy_remain1 = myplane1.energy / myplane.Myplane.energy if energy_remain1 > 0.5: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color,\ (myplane1.rect.left, myplane1.rect.bottom + 5),\ (myplane1.rect.left + myplane1.rect.width * energy_remain1,\ myplane1.rect.bottom + 5), 2) else: if not (delay % 3): # here we draw the destory pictures of the plane screen.blit( myplane1.destroy_images[myplane1_destroy_index], myplane1.rect) myplane1_destroy_index = (myplane1_destroy_index + 1) % 4 if myplane1_destroy_index == 0: life_num -= 1 myplane1.reset() pygame.time.set_timer(invincible_time, 3 * 1000) # here we check the condition of the enemy3 if boss1.active: boss1.move() screen.blit(boss1.image, boss1.rect) # here we draw the total blood of the enemy plane pygame.draw.line(screen, BLACK, \ (boss1.rect.left, boss1.rect.bottom - 50),\ (boss1.rect.right, boss1.rect.bottom - 50),\ 2) # when the energy is bigger than 20%, it will be green. else, it will be red energy_remain2 = boss1.energy / enemy.Enemy8.energy if energy_remain2 > 0.30: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color,\ (boss1.rect.left, boss1.rect.bottom - 50),\ (boss1.rect.left + boss1.rect.width * energy_remain2,\ boss1.rect.bottom - 50), 2) else: if level == 7: if not (delay % 3): # here we draw the destory pictures of the plane screen.blit(boss1.destroy_images[boss_destroy_index], boss1.rect) boss_destroy_index = (boss_destroy_index + 1) % 4 if boss_destroy_index == 0: score += 10000 life_num -= life_num boss1.reset() # here we draw the enemy bullet if bullet5.active: screen.blit(bullet5.image, bullet5.rect) bullet5.move() if bullet5.rect.centerx > myplane1.rect.centerx and bullet5.rect.top < myplane1.rect.top: bullet5.rect.left -= 2 if bullet5.rect.centerx < myplane1.rect.centerx and bullet5.rect.top < myplane1.rect.top: bullet5.rect.left += 2 else: if not level == 7: if e3.rect.top > 0 and e3.rect.top < 800: bullet5.reset((e3.rect.centerx, e3.rect.bottom)) if bullet51.active: screen.blit(bullet51.image, bullet51.rect) bullet51.move() else: if not level == 7: if e21.rect.top > 0 and e21.rect.top < 800: bullet51.reset((e21.rect.centerx, e21.rect.bottom)) if bullet52.active: screen.blit(bullet52.image, bullet52.rect) bullet52.move() else: if not level == 7: if e22.rect.top > 0 and e22.rect.top < 800: bullet52.reset((e22.rect.centerx, e22.rect.bottom)) if bullet53.active: screen.blit(bullet53.image, bullet53.rect) bullet53.move() else: if not level == 7: if e23.rect.top > 0 and e23.rect.top < 800: bullet53.reset((e23.rect.centerx, e23.rect.bottom)) if bullet54.active: screen.blit(bullet54.image, bullet54.rect) bullet54.move() else: if not level == 7: if e24.rect.top > 0 and e24.rect.top < 800: bullet54.reset((e24.rect.centerx, e24.rect.bottom)) if bullet55.active: screen.blit(bullet55.image, bullet55.rect) bullet55.move() else: if not level == 7: if e25.rect.top > 0 and e25.rect.top < 800: bullet55.reset((e25.rect.centerx, e25.rect.bottom)) # here we shot the bullets if not (delay % 10): if is_super_bullet: bullets = bullet2 bullets[bullet2_index].reset( (myplane1.rect.centerx - 13, myplane1.rect.centery)) bullets[bullet2_index + 1].reset( (myplane1.rect.centerx + 13, myplane1.rect.centery)) bullet3[bullet3_index].reset( (myplane1.rect.centerx + 23, myplane1.rect.centery)) bullet4[bullet4_index].reset( (myplane1.rect.centerx - 23, myplane1.rect.centery)) bullet2_index = (bullet2_index + 2) % bullet2_number bullet3_index = (bullet3_index + 1) % bullet3_number bullet4_index = (bullet4_index + 1) % bullet4_number else: bullets = bullet1 bullets[bullet1_index].reset( (myplane1.rect.centerx - 13, myplane1.rect.centery)) bullets[bullet1_index + 1].reset( (myplane1.rect.centerx + 13, myplane1.rect.centery)) bullet1_index = (bullet1_index + 2) % bullet1_number # here we draw the boss bullet if boss1.active: if not (delay % 40): bossbullets = bullet6 bossbullets[bullet6_index].reset( (boss1.rect.centerx - 300, boss1.rect.centery)) bossbullets[bullet6_index + 1].reset( (boss1.rect.centerx - 100, boss1.rect.centery)) bossbullets[bullet6_index + 2].reset( (boss1.rect.centerx + 100, boss1.rect.centery)) bossbullets[bullet6_index + 3].reset( (boss1.rect.centerx + 300, boss1.rect.centery)) bullet6_index = (bullet6_index + 4) % bullet6_number # here we check if the bullet collides witg the plane if level == 7 and boss1.active: for v in bossbullets: if v.active: if energy_remain2 >= 0.9: v.move() if energy_remain2 >= 0.8 and energy_remain2 < 0.9: v.move() v.move1() if energy_remain2 >= 0.7 and energy_remain2 < 0.8: v.move() v.move3() if energy_remain2 >= 0.6 and energy_remain2 < 0.7: v.move() v.move2() if energy_remain2 >= 0.5 and energy_remain2 < 0.6: v.move() v.move3() if energy_remain2 >= 0.4 and energy_remain2 < 0.5: v.move() v.rect.top += 1 v.move1() if energy_remain2 >= 0.3 and energy_remain2 < 0.4: v.move() v.rect.top += 2 v.move2() if energy_remain2 >= 0.2 and energy_remain2 < 0.3: v.move() if energy_remain2 < 0.2: v.move() if v.rect.centerx > myplane1.rect.centerx and v.rect.top < myplane1.rect.top: v.rect.left -= 2 if v.rect.centerx < myplane1.rect.centerx and v.rect.top < myplane1.rect.top: v.rect.left += 2 screen.blit(v.image, v.rect) bossbullet_down = pygame.sprite.spritecollide( v, my_plane, False, pygame.sprite.collide_mask) if bossbullet_down and not myplane1.invincible: myplane1.energy -= 1 if myplane1.energy == 0: myplane1.active = False v.active = False # here we check if the bullet collides with the enemy plane 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) enemy3_hit = pygame.sprite.spritecollide( b, enemy3, False, pygame.sprite.collide_mask) enemy2_hit = pygame.sprite.spritecollide( b, enemy2, False, pygame.sprite.collide_mask) boss_hit = pygame.sprite.spritecollide( b, boss, False, pygame.sprite.collide_mask) if enemy_hit: b.active = False for e in enemy_hit: # here we check which type of planes is attacked if e in enemy2: e.energy -= 1 if e.energy == 0: e.active = False else: e.active = False if enemy3_hit: b.active = False # here we check which type of planes is attacked e3.energy -= 1 if e3.energy == 0: e3.active = False if enemy2_hit: b.active = False for z in enemy2_hit: z.energy -= 1 if z.energy == 0: z.active = False if boss_hit: b.active = False boss1.energy -= 1 if boss1.energy == 0: boss1.active = False level == 8 for x in bullet3: if x.active: x.move1() x.move() screen.blit(x.image, x.rect) enemy_hit = pygame.sprite.spritecollide( x, enemies, False, pygame.sprite.collide_mask) enemy3_hit = pygame.sprite.spritecollide( x, enemy3, False, pygame.sprite.collide_mask) enemy2_hit = pygame.sprite.spritecollide( x, enemy2, False, pygame.sprite.collide_mask) boss_hit = pygame.sprite.spritecollide( x, boss, False, pygame.sprite.collide_mask) if enemy_hit: x.active = False for e in enemy_hit: # here we check which type of planes is attacked if e in enemy2: e.energy -= 1 if e.energy == 0: e.active = False else: e.active = False if enemy3_hit: x.active = False # here we check which type of planes is attacked e3.energy -= 1 if e3.energy == 0: e3.active = False if enemy2_hit: x.active = False for z in enemy2_hit: z.energy -= 1 if z.energy == 0: z.active = False if boss_hit: x.active = False boss1.energy -= 1 if boss1.energy == 0: boss1.active = False level == 8 for y in bullet4: if y.active: y.move1() y.move() screen.blit(y.image, y.rect) enemy_hit = pygame.sprite.spritecollide( y, enemies, False, pygame.sprite.collide_mask) enemy3_hit = pygame.sprite.spritecollide( y, enemy3, False, pygame.sprite.collide_mask) enemy2_hit = pygame.sprite.spritecollide( y, enemy2, False, pygame.sprite.collide_mask) boss_hit = pygame.sprite.spritecollide( y, boss, False, pygame.sprite.collide_mask) if enemy_hit: y.active = False for e in enemy_hit: # here we check which type of planes is attacked if e in enemy2: e.energy -= 1 if e.energy == 0: e.active = False else: e.active = False if enemy3_hit: y.active = False # here we check which type of planes is attacked e3.energy -= 1 if e3.energy == 0: e3.active = False if enemy2_hit: y.active = False for z in enemy2_hit: z.energy -= 1 if z.energy == 0: z.active = False if boss_hit: y.active = False boss1.energy -= 1 if boss1.energy == 0: boss1.active = False level == 8 # here we check the condition of the enemy3 if e3.active and not level == 7: e3.move() screen.blit(e3.image, e3.rect) # here we draw the total blood of the enemy plane pygame.draw.line(screen, BLACK, \ (e3.rect.left, e3.rect.top - 5),\ (e3.rect.right, e3.rect.top - 5),\ 2) # when the energy is bigger than 20%, it will be green. else, it will be red energy_remain = e3.energy / enemy.Enemy3.energy if energy_remain > 0.35: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color,\ (e3.rect.left, e3.rect.top - 5),\ (e3.rect.left + e3.rect.width * energy_remain,\ e3.rect.top - 5), 2) else: if not level == 7: if not (delay % 3): # here we draw the destory pictures of the plane screen.blit(e3.destroy_images[en3_destroy_index], e3.rect) en3_destroy_index = (en3_destroy_index + 1) % 4 if en3_destroy_index == 0: score += 1000 e3.reset() if e3.rect.top > 960 and not level == 7: e3.reset() for each in enemy2: if each.active and not level == 7: each.move() screen.blit(each.image, each.rect) # here we draw the total blood of the enemy plane pygame.draw.line(screen, BLACK, \ (each.rect.left, each.rect.top - 5),\ (each.rect.right, each.rect.top - 5),\ 2) # when the energy is bigger than 20%, it will be green. else, it will be red energy_remain = each.energy / enemy.Enemy2.energy if energy_remain > 0.35: 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 level == 7: if not (delay % 3): # here we draw the destory pictures of the plane screen.blit(each.destroy_images[e2_destroy_index], each.rect) e2_destroy_index = (e2_destroy_index + 1) % 4 if e2_destroy_index == 0: score += 500 each.reset() if each.rect.top > 960 and not level == 7: each.reset() for each in enemy1: if each.active and not level == 7: each.move() screen.blit(each.image, each.rect) else: if not level == 7: if not (delay % 3): # here we draw the destory pictures of the plane 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() for each in enemy4: if each.active and not level == 7: each.move() screen.blit(each.image, each.rect) else: if not level == 7: if not (delay % 3): # here we draw the destory pictures of the plane screen.blit(each.destroy_images[e4_destroy_index], each.rect) e4_destroy_index = (e4_destroy_index + 1) % 4 if e4_destroy_index == 0: score += 100 each.reset() for each in enemy5: if each.active and not level == 7: each.move() screen.blit(each.image, each.rect) else: if not level == 7: if not (delay % 3): # here we draw the destory pictures of the plane screen.blit(each.destroy_images[e5_destroy_index], each.rect) e5_destroy_index = (e5_destroy_index + 1) % 4 if e5_destroy_index == 0: score += 100 each.reset() for each in enemy6: if each.active and not level == 7: each.move() screen.blit(each.image, each.rect) else: if not level == 7: if not (delay % 3): # here we draw the destory pictures of the plane screen.blit(each.destroy_images[e6_destroy_index], each.rect) e6_destroy_index = (e6_destroy_index + 1) % 4 if e6_destroy_index == 0: score += 100 each.reset() for each in enemy7: if each.active and not level == 7: each.move() screen.blit(each.image, each.rect) else: if not level == 7: if not (delay % 3): # here we draw the destory pictures of the plane screen.blit(each.destroy_images[e7_destroy_index], each.rect) e7_destroy_index = (e7_destroy_index + 1) % 4 if e7_destroy_index == 0: score += 100 each.reset() # here we draw the score score_text = score_font.render("Score : %s" % str(score), True, BLACK) screen.blit(score_text, (10, 5)) # here we creat the ending elif life_num == 0: # here we stop dropping the support pygame.time.set_timer(supply_time, 0) if not recorded: recorded = True # here we read the highest record with open("record.txt.txt", "r") as f: record_score = int(f.read()) # here we change the highest record if score > record_score: with open("record.txt.txt", "w") as f: f.write(str(score)) # here we draw the ending picture record_score_text = score_font.render( "Best was : %d" % record_score, True, BLACK) screen.blit(record_score_text, (50, 50)) gameover_text1 = gameover_font.render("Your Score", True, BLACK) 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, BLACK) 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) # here we set the mouse # if the player click left mouse if pygame.mouse.get_pressed()[0]: # here we get the coordination of the mouse pos = pygame.mouse.get_pos() # if the player click restart if again_rect.left < pos[0] < again_rect.right and \ again_rect.top < pos[1] < again_rect.bottom: main() # if the player click exit elif gameover_rect.left < pos[0] < gameover_rect.right and \ gameover_rect.top < pos[1] < gameover_rect.bottom: pygame.quit() sys.exit() # here we draw the bomb 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)) # here we draw the number of lives of myplane if life_num: for i in range(life_num): screen.blit(life_image, \ (width-(i+1)*life_rect.width+30, \ height-life_rect.height+35)) # here we draw the pause and continue picture screen.blit(paused_image, paused_rect) # here we change the value of delay delay -= 1 if not delay: delay = 120 pygame.display.flip() clock.tick(60)
def main(): # 播放背景音乐 无限循环 pygame.mixer.music.play(-1) # 暂停按钮 pause_rect = pause_nor_image.get_rect() pause_rect.right, pause_rect.top = (width - 10, 10) pause_image = pause_nor_image # 炸弹 bomb_rect = bomb_image.get_rect() bomb_rect.left, bomb_rect.bottom = (10, height - 10) bomb_num = 3 # 设置难度 level = 1 # 帧数设置 clock = pygame.time.Clock() # 血槽颜色 white = (255, 255, 255) green = (0, 255, 0) red = (255, 0, 0) black = (0, 0, 0) orange = (255, 165, 0) # 分数统计 score = 0 score_font = pygame.font.Font('font/font.ttf', 36) # 用于限制文件打开次数 recoded = False # 难度字体 level_font = pygame.font.Font('font/font.ttf', 18) # 炸弹字体 bomb_font = pygame.font.Font('font/font.ttf', 48) # 结束界面字体 record_font = pygame.font.Font('font/font.ttf', 36) end_score_font = pygame.font.Font('font/font.ttf', 56) running = True pause = False # 实例化我方飞机 me = myplane.Myplane(bg_size) # 命数 life_image = pygame.image.load('image/life.png') life_rect = life_image.get_rect() life_num = 3 # 载入补给 bullet_supply = supply.Bullet_Supply(bg_size) bomb_supply = supply.Bomb_Supply(bg_size) laser_supply = supply.Laser_Supply(bg_size) wave_supply = supply.Wave_Supply(bg_size) defend_supply = supply.Defend_Supply(bg_size) # 自定义补给时间 SUPPLY_TIME = USEREVENT # 剩余的下一个补给来的时间 during_time = random.randint(10, 30) * 1000 pygame.time.set_timer(SUPPLY_TIME, during_time) start_time = pygame.time.get_ticks() # 定义防护罩时间 DEFEND_TIME = USEREVENT + 3 # 防护罩闪烁计时 defend_num = 0 # 剩余的防护罩时间 defend_during_time = 10 * 1000 # 超级子弹定时器 # BULLET2_TIME = USEREVENT + 1 # 无敌时间计时器 INVINCIBLE_TIME = USEREVENT + 2 # 剩余的无敌的时间 invincible_during_time = 3 * 1000 # 标志是否使用子弹类型 bullet_type = 1 # 我方飞机毁灭动画索引 me_down_index = 0 # 实例化敌方飞机 enemies = pygame.sprite.Group() small_enemies = pygame.sprite.Group() add_small_enemys(small_enemies, enemies, 15) mid_enemies = pygame.sprite.Group() add_mid_enemys(mid_enemies, enemies, 8) big_enemies = pygame.sprite.Group() add_big_enemys(big_enemies, enemies, 5) boss = enemy.Boss(bg_size) # 载入背景 bg = background.Background1(bg_size) cloud = background.Cloud(bg_size) cloud_switch = False # 控制背景类型 bg_type = 0 # 实例化子弹 bullet1 = [] bullet1_index = 0 bullet1_num = 4 for i in range(bullet1_num): bullet1.append(bullet.Bullet1((0, 0))) # 实例化子弹2 bullet2 = [] bullet2_index = 0 bullet2_num = 8 for i in range(bullet2_num): bullet2.append(bullet.Bullet2((0, 0))) # 实例化子弹3 bullet3 = [] bullet3_index = 0 bullet3_num = 20 for i in range(bullet3_num): bullet3.append(bullet.Bullet3((0, 0))) # 实例化子弹4 bullet4 = [] bullet4_switch = 1 bullet4.append(bullet.Bullet4((0, 0))) # 实例化子弹5 bullet5 = [] bullet5.append(bullet.Bullet5((0, 0))) # 实例化冲击波 wave = bullet.Wave((0, 0)) wave_flage = False # 实例化防护罩 defend = bullet.Defend((0, 0)) # 实例化炸弹爆炸 bomb_fire = bullet.BombFire((0, 0)) # 实例化Boss子弹 boss_bullet = bullet.BossBullet((512, -500)) boss_bullettwo = [] boss_bullettwo_index = 0 boss_bullettwo_num = 4 boss_bullettwogroup = pygame.sprite.Group() for i in range(boss_bullettwo_num): boss_bullettwo.append(bullet.BossBulletTwo((0, 0))) for i in boss_bullettwo: boss_bullettwogroup.add(i) # Boss激光实例化 boss_laser = bullet.BossLaser((0, 0)) # 子弹放在一起 bullet_fire1 = [] bullet_fire1.extend(bullet1) bullet_fire1.extend(bullet2) bullet_fire1.extend(bullet3) bullet_fire2 = [] bullet_fire2.extend(bullet4) bullet_fire2.extend(bullet5) # 切换飞机的延迟 delay = 100 # 用于切换飞机 switch_image = True # 作弊开关 cheat = 0 # 程序启动 while running: # 暂停设置 mouse_left, mouse_top = pygame.mouse.get_pos() if pause_rect.collidepoint(mouse_left, mouse_top): if not pause: pause_image = pause_pressed_image else: pause_image = resume_pressed_image else: if not pause: pause_image = pause_nor_image else: pause_image = resume_nor_image for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type == MOUSEBUTTONDOWN: # 点击暂停 if event.button == 1 and pause_rect.collidepoint(event.pos): pause = not pause if pause: pause_time = pygame.time.get_ticks() # 刷新剩余时间 if defend.active: defend_during_time = defend_during_time - (pause_time - defend_start_time) if me.invincible and not defend.active: invincible_during_time = invincible_during_time - (pause_time - invincible_start_time) during_time = during_time - (pause_time-start_time) # 暂停补给计时器 pygame.time.set_timer(DEFEND_TIME, 0) pygame.time.set_timer(INVINCIBLE_TIME, 0) pygame.time.set_timer(SUPPLY_TIME, 0) pygame.mixer.music.pause() pygame.mixer.pause() else: pygame.time.set_timer(DEFEND_TIME, defend_during_time) pygame.time.set_timer(INVINCIBLE_TIME, invincible_during_time) pygame.time.set_timer(SUPPLY_TIME, during_time) defend_start_time = pygame.time.get_ticks() invincible_start_time = pygame.time.get_ticks() start_time = pygame.time.get_ticks() pygame.mixer.music.unpause() pygame.mixer.unpause() # 结束界面的选择 if life_num == 0: if event.button == 1 and again_rect.collidepoint(event.pos): main() elif event.button == 1 and gameover_rect.collidepoint(event.pos): pygame.quit() sys.exit() # 发射炸弹 if event.type == KEYDOWN and not pause: if event.key == K_SPACE and bomb_num: bomb_sound.play() bomb_num -= 1 bomb_fire.reset(me.rect.center) bomb_fire.active = True bomb_fire_pos = me.rect.center # 作弊 if cheat != 4: if event.key == K_r: cheat = 1 elif event.key == K_y and cheat == 1: cheat = 2 elif event.key == K_n and cheat == 2: cheat = 3 elif event.key == K_b and cheat == 3: cheat = 4 else: cheat = 0 # 补给 if event.type == SUPPLY_TIME: supply_sound.play() during_time = random.randint(10, 30) * 1000 pygame.time.set_timer(SUPPLY_TIME, during_time) start_time = pygame.time.get_ticks() if random.randint(0, 7-level) == 0: laser_supply.reset() else: supply_choice = random.choice([1, 2, 3, 4]) if supply_choice == 1: bullet_supply.reset() elif supply_choice == 2: bomb_supply.reset() elif supply_choice == 3: wave_supply.reset() elif supply_choice == 4: defend_supply.reset() # 无敌时间结束 if event.type == INVINCIBLE_TIME: pygame.time.set_timer(INVINCIBLE_TIME, 0) invincible_during_time = 3 * 1000 me.invincible = False # 防护罩时间结束 if event.type == DEFEND_TIME: pygame.time.set_timer(DEFEND_TIME, 0) defend_during_time = 10 * 1000 defend.active = False me.invincible = False defend_num = 0 # 绘制背景 if bg_type == 2: # 载入背景 bg = background.Background2(bg_size) bg_type = 0 if bg_type == 3: # 载入背景 bg = background.Background3(bg_size) bg_type = 0 if not pause and not delay % 2: bg.move() screen.blit(bg.background1, bg.background1_rect) screen.blit(bg.background2, bg.background2_rect) if (level == 3 or level == 5) and cloud_switch: if not pause: cloud.move() screen.blit(cloud.image, cloud.rect) if level == 3 and cloud.rect.centery == height // 2: bg_type = 2 if level == 5 and cloud.rect.centery == height // 2: bg_type = 3 if cloud.rect.bottom == 0: cloud_switch = False if life_num and not pause: # 检测键盘操作 key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[KEYUP]: me.moveUp() if key_pressed[K_s] or key_pressed[KEYDOWN]: 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() # 绘制补给,并检测碰撞 # 弹2 if bullet_supply.active: bullet_supply.move() screen.blit(bullet_supply.image, bullet_supply.rect) if pygame.sprite.collide_mask(me, bullet_supply): get_bullet_sound.play() if bullet_type == 2 or bullet_type == 3: bullet_type = 3 else: bullet_type = 2 bullet_supply.active = False # 激光 if laser_supply.active: laser_supply.move() screen.blit(laser_supply.image, laser_supply.rect) if pygame.sprite.collide_mask(me, laser_supply): get_bullet_sound.play() if bullet_type == 4 or bullet_type == 5: bullet_type = 5 else: bullet_type = 4 laser_supply.active = False # 炸弹 if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(me, bomb_supply): get_bomb_sound.play() if bomb_num < 3: bomb_num += 1 bomb_supply.active = False # 冲击波 if wave_supply.active: wave_supply.move() screen.blit(wave_supply.image, wave_supply.rect) if pygame.sprite.collide_mask(me, wave_supply): get_bomb_sound.play() wave_flage = True wave_supply.active = False # 防护罩 if defend_supply.active: defend_supply.move() screen.blit(defend_supply.image, defend_supply.rect) if pygame.sprite.collide_mask(me, defend_supply): get_bomb_sound.play() defend.active = True pygame.time.set_timer(DEFEND_TIME, defend_during_time) defend_start_time = pygame.time.get_ticks() defend_supply.active = False # 检测我方飞机是否被撞 if cheat != 4: enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask) # 返回碰撞的列表,以mask方法检测 if enemies_down and not me.invincible: me.active = False for each in enemies_down: each.active = False if pygame.sprite.collide_mask(me, boss): if not me.invincible: me.active = False if boss_bullet.active: if pygame.sprite.collide_mask(boss_bullet, me) and not me.invincible: me.active = False boss_bullet.active = False if pygame.sprite.spritecollide(me, boss_bullettwogroup, False, pygame.sprite.collide_mask) and not me.invincible: me.active = False if boss_laser.active: if pygame.sprite.collide_mask(boss_laser, me) and not me.invincible: me.active = False # 难度变化 if level == 1 and score >= 50000: level = 2 upgrade_sound.play() add_small_enemys(small_enemies, enemies, 5) add_mid_enemys(mid_enemies, enemies, 1) for each in small_enemies: each.speed += 1 elif level == 2 and score >= 100000: level = 3 cloud_switch = True upgrade_sound.play() add_small_enemys(small_enemies, enemies, 5) add_mid_enemys(mid_enemies, enemies, 3) add_big_enemys(big_enemies, enemies, 2) for each in small_enemies: each.speed += 1 for each in mid_enemies: each.speed += 1 elif level == 3 and score >= 150000: level = 4 upgrade_sound.play() add_small_enemys(small_enemies, enemies, 5) add_mid_enemys(mid_enemies, enemies, 3) add_big_enemys(big_enemies, enemies, 2) for each in small_enemies: each.speed += 1 for each in mid_enemies: each.speed += 1 for each in big_enemies: each.speed += 1 elif level == 4 and score >= 200000: level = 5 cloud_switch = True upgrade_sound.play() add_small_enemys(small_enemies, enemies, 5) add_mid_enemys(mid_enemies, enemies, 3) add_big_enemys(big_enemies, enemies, 2) for each in small_enemies: each.speed += 2 for each in mid_enemies: each.speed += 2 for each in big_enemies: each.speed += 1 elif level == 5 and score >= 270000: level = 6 score_time = pygame.time.get_ticks() boss.active = True for e in enemies: e.active = False # 绘制我方飞机 if me.active: if not me.invincible or defend.active: if not (delay % 5): switch_image = not switch_image if switch_image: screen.blit(me.image1, me.rect) else: screen.blit(me.image2, me.rect) elif me.invincible and defend.active == False: if not (delay % 3): if not (delay % 5): switch_image = not switch_image if switch_image: screen.blit(me.image1, me.rect) else: screen.blit(me.image2, me.rect) else: # 毁灭 if me_down_index == 0: me_down_sound.play() screen.blit(me.down_image[me_down_index], me.rect) if not delay % 5: me_down_index = (me_down_index + 1) % 4 if me_down_index == 0: if life_num > 0: life_num -= 1 me.reset() bullet_type = 1 bomb_num = 3 wave_flage = False # 无敌时间 me.invincible = True pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000) invincible_start_time = pygame.time.get_ticks() # 绘制子弹 if not (delay % 10): if bullet_type == 2: bullet2[bullet2_index].reset((me.rect.centerx - 38, me.rect.centery)) # 只有这里调用了子弹的reset bullet2[bullet2_index + 1].reset((me.rect.centerx + 26, me.rect.centery)) # 只有这里调用了子弹的reset bullet2_index = (bullet2_index + 2) % bullet2_num elif bullet_type == 3: bullet3[bullet3_index].reset((me.rect.centerx - 38, me.rect.centery)) # 只有这里调用了子弹的reset bullet3[bullet3_index + 1].reset((me.rect.centerx + 26, me.rect.centery)) # 只有这里调用了子弹的reset bullet3[bullet3_index + 2].reset(me.rect.midtop) # 只有这里调用了子弹的reset bullet3[bullet3_index + 3].reset((me.rect.centerx - 18, me.rect.centery)) # 只有这里调用了子弹的reset bullet3[bullet3_index + 4].reset((me.rect.centerx + 6, me.rect.centery)) # 只有这里调用了子弹的reset bullet3_index = (bullet3_index + 5) % bullet3_num elif bullet_type == 1: bullet1[bullet1_index].reset(me.rect.midtop) # 只有这里调用了子弹的reset bullet1_index = (bullet1_index + 1) % bullet1_num if bullet_type == 4: bullet4[0].reset(me.rect.midtop) # 只有这里调用了子弹的reset else: bullet4[0].active = False if bullet_type == 5: bullet5[0].reset(me.rect.midtop) # 只有这里调用了子弹的reset else: bullet5[0].active = False # 冲击波绘制 if not delay % 200: if wave_flage: wave.reset(me.rect.midtop) # 防护罩绘制 if defend.active: defend_num += 1 me.invincible = True defend.reset(me.rect.center) if defend_num < 420: screen.blit(defend.image, defend.rect) else: if not delay % 5: screen.blit(defend.image, defend.rect) # 检测防护罩是否被撞 enemies_down = pygame.sprite.spritecollide(defend, enemies, False, pygame.sprite.collide_mask) # 返回碰撞的列表,以mask方法检测 for each in enemies_down: each.active = False # 炸弹爆炸绘制 if bomb_fire.active: bomb_fire.move(bomb_fire_pos) screen.blit(bomb_fire.image, bomb_fire.rect) enemies_down = pygame.sprite.spritecollide(bomb_fire, enemies, False, pygame.sprite.collide_mask) for each in enemies_down: each.active = False # Boss与炸弹碰撞检测 if boss.active: if pygame.sprite.collide_mask(bomb_fire, boss) and boss.rect.top > 0: if not delay % 5: boss.hit = True boss.energy -= 30 if boss.energy <= 0: boss.active = False # Boss子弹绘制 if boss.active and not delay % 400: boss_bullet.reset(boss.rect.center) if boss.active and not delay % 50 and boss.energy <= 0.5 * enemy.Boss.energy: boss_bullettwo[boss_bullettwo_index].reset(boss.rect.midtop) boss_bullettwo_index = (boss_bullettwo_index + 1) % boss_bullettwo_num # 子弹移动 碰撞检测 # 子弹检测 for b in bullet_fire1: 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 # active = False并不会毁灭子弹,子弹只是不再显示,也不再检测碰撞, 不再移动 for e in enemy_hit: if e in small_enemies: e.active = False else: e.hit = True e.energy -= 1 if e.energy <= 0: e.active = False # Boss与子弹碰撞检测 if boss.active: if pygame.sprite.collide_mask(b, boss) and boss.rect.top > 0: b.active = False boss.hit = True boss.energy -= 1 if boss.energy <= 0: boss.active = False # 激光检测 for b in bullet_fire2: if b.active: if bullet4_switch == 0: screen.blit(b.image1, b.rect) elif bullet4_switch == 1: screen.blit(b.image2, b.rect) enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask) if enemy_hit: for e in enemy_hit: if e.rect.bottom > 0: if e in small_enemies: e.active = False else: if bullet_type == 4: if not delay % 8: e.hit = True e.energy -= 1 if e.energy <= 0: e.active = False elif bullet_type == 5: if not delay % 8: e.hit = True e.energy -= 3 if e.energy <= 0: e.active = False # Boss与激光碰撞检测 if boss.active: if pygame.sprite.collide_mask(b, boss) and boss.rect.top > 0: if bullet_type == 4: if not delay % 10: boss.hit = True boss.energy -= 3 if boss.energy <= 0: boss.active = False elif bullet_type == 5: if not delay % 10: boss.hit = True boss.energy -= 6 if boss.energy <= 0: boss.active = False # 冲击波检测 if wave.active: wave.move() if bullet4_switch == 0: screen.blit(wave.image1, wave.rect) elif bullet4_switch == 1: screen.blit(wave.image2, wave.rect) enemy_hit = pygame.sprite.spritecollide(wave, enemies, False, pygame.sprite.collide_mask) if enemy_hit: for e in enemy_hit: if e in small_enemies: e.active = False else: if not delay % 12: e.hit = True e.energy = int(e.energy * 0.9 - 7) if e.energy <= 0: e.active = False # Boss与冲击波碰撞检测 if boss.active: if pygame.sprite.collide_mask(wave, boss) and boss.rect.top > 0: if not delay % 12: boss.hit = True boss.energy = int(boss.energy * 0.95 - 7) if boss.energy <= 0: boss.active = False # Boss子弹绘制 if boss.active: if boss_bullet.active: boss_bullet.move() screen.blit(boss_bullet.image[boss_bullet.index], boss_bullet.rect) if not delay % 10 and boss_bullet.index != 7: boss_bullet.index += 1 # 二号Boss子弹 if boss.energy <= 0.5 * enemy.Boss.energy: for b in boss_bullettwo: if b.active: b.move() screen.blit(b.image, b.rect) elif boss.energy <= 0.2 * enemy.Boss.energy: # 子弹消失时出现激光 boss_laser.reset(b.rect.midtop) if switch_image: screen.blit(boss_laser.image1, boss_laser.rect) else: screen.blit(boss_laser.image2, boss_laser.rect) if not delay % 5: bullet4_switch = (bullet4_switch + 1) % 2 # 绘制敌方飞机 # Boss if boss.active: boss.move() if boss.hit: if boss.energy > 0.5 * enemy.Boss.energy: screen.blit(boss.image_hit, boss.rect) elif 0.5 * enemy.Boss.energy >= boss.energy > 0.2 * enemy.Boss.energy: screen.blit(boss.down_image[1], boss.rect) else: screen.blit(boss.down_image[2], boss.rect) boss.hit = False else: screen.blit(boss.image, boss.rect) # 绘制血槽 pygame.draw.line(screen, white, (boss.rect.left, boss.rect.top - 5), (boss.rect.right, boss.rect.top - 5), 5) # 不同血量显示不同颜色 energy_remain = boss.energy / enemy.Boss.energy if energy_remain > 0.5: energy_color = green elif 0.5 >= energy_remain > 0.2: energy_color = orange else: energy_color = red pygame.draw.rect(screen, energy_color, (boss.rect.left, boss.rect.top - 10, int((boss.rect.right - boss.rect.left) * energy_remain), 10)) # 绘制血槽框 pygame.draw.rect(screen, black, (boss.rect.left, boss.rect.top - 10, boss.rect.width, 10), 2) # 即将出现时播放音效 if boss.rect.bottom == -18: boss_sound.play() else: # 毁灭 if boss.boss_down_index == 0 and boss.rect.top > 0: boss_down_sound.play() score_time_end = pygame.time.get_ticks() score += 200000 - (score_time_end - score_time) screen.blit(boss.down_image[boss.boss_down_index], boss.rect) if not (delay % 10) and boss.rect.top > 0: boss.boss_down_index = (boss.boss_down_index + 1) % 12 if boss.boss_down_index == 0: life_num = 0 # 大型飞机 for each in big_enemies: if each.active: each.move(boss.active) 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, white, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 5) # 不同血量显示不同颜色 energy_remain = each.energy / enemy.BigEnemy.energy if energy_remain > 0.5: energy_color = green elif 0.5 >= energy_remain > 0.2: energy_color = orange else: energy_color =red pygame.draw.rect(screen, energy_color, (each.rect.left, each.rect.top - 10, int((each.rect.right - each.rect.left) * energy_remain), 10)) # 绘制血槽框 pygame.draw.rect(screen, black, (each.rect.left, each.rect.top - 10, each.rect.width, 10), 2) # 即将出现时播放音效 if each.rect.bottom == -50 or each.rect.bottom == -51 or each.rect.bottom == -52: enemy3_flying_sound.play(-1) if each.rect.top > height: enemy3_flying_sound.stop() else: # 毁灭 enemy3_flying_sound.stop() if each.e3_down_index == 0: enemy3_down_sound.play() screen.blit(each.down_image[each.e3_down_index], each.rect) if not (delay % 5): each.e3_down_index = (each.e3_down_index + 1) % 6 if each.e3_down_index == 0: score += 10000 if not boss.active: each.reset() big_enemies.remove(each) while True: if pygame.sprite.spritecollide(each, big_enemies, False, pygame.sprite.collide_mask): each.reset() else: break big_enemies.add(each) else: big_enemies.remove(each) enemies.remove(each) # 中型飞机 for each in mid_enemies: if each.active: each.move(boss.active) if each.hit: screen.blit(each.image_hit, each.rect) each.hit = False else: screen.blit(each.image, each.rect) # 绘制血槽 pygame.draw.line(screen, white, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 5) # 不同血量显示不同颜色 energy_remain = (each.energy / enemy.MidEnemy.energy) if energy_remain > 0.5: energy_color = green elif 0.5 >= energy_remain > 0.2: energy_color = orange else: energy_color = red pygame.draw.rect(screen, energy_color, (each.rect.left, each.rect.top - 10, int((each.rect.right - each.rect.left) * energy_remain), 10)) # 绘制血槽框 pygame.draw.rect(screen, black, (each.rect.left, each.rect.top - 10, each.rect.width, 10), 2) else: # 毁灭 if each.e2_down_index == 0: enemy2_down_sound.play() screen.blit(each.down_image[each.e2_down_index], each.rect) if not (delay % 5): each.e2_down_index = (each.e2_down_index + 1) % 4 if each.e2_down_index == 0: score += 3000 if not boss.active: each.reset() mid_enemies.remove(each) while True: if pygame.sprite.spritecollide(each, mid_enemies, False, pygame.sprite.collide_mask): each.reset() else: break mid_enemies.add(each) else: mid_enemies.remove(each) enemies.remove(each) # 小型飞机 for each in small_enemies: if each.active: each.move(boss.active) screen.blit(each.image, each.rect) else: # 毁灭 if each.e1_down_index == 0: enemy1_down_sound.play() screen.blit(each.down_image[each.e1_down_index], each.rect) if not (delay % 5): each.e1_down_index = (each.e1_down_index + 1) % 4 if each.e1_down_index == 0: score += 1000 if not boss.active: each.reset() small_enemies.remove(each) while True: if pygame.sprite.spritecollide(each, small_enemies, False, pygame.sprite.collide_mask): each.reset() else: break small_enemies.add(each) else: small_enemies.remove(each) enemies.remove(each) # 绘制炸弹 bomb_text = bomb_font.render('X %d' % bomb_num, True, white) bomb_text_rect = bomb_rect.copy() bomb_text_rect.left = bomb_rect.width + 20 screen.blit(bomb_image, bomb_rect) screen.blit(bomb_text, bomb_text_rect) # 绘制生命数 for i in range(life_num): screen.blit(life_image, (width - 10 - (i + 1) * (life_rect.width + 20), height - 10 - life_rect.height)) # 绘制结束画面 elif life_num == 0: pygame.mixer.music.stop() pygame.mixer.stop() pygame.time.set_timer(SUPPLY_TIME, 0) if not recoded: # 读取历史最高分 with open('record.txt', 'r') as f: record_score = int(f.read()) # 如果玩家打破纪录 if score > record_score: record_score = score with open('record.txt', 'w') as f: f.write(str(score)) recoded = True # 结束界面 record_score_text = record_font.render('BestScore : %s' % record_score, True, white) screen.blit(record_score_text, (10, 10)) end_score_text1 = end_score_font.render('Your Score', True, white) end_score_text2 = end_score_font.render(str(score), True, white) end_score_rect1 = end_score_text1.get_rect() end_score_rect2 = end_score_text2.get_rect() screen.blit(end_score_text1, ((width - end_score_rect1.width) // 2, (height - end_score_rect1.height) // 2 - 80)) screen.blit(end_score_text2, ((width - end_score_rect2.width) // 2, (height - end_score_rect1.height) // 2 - 100 + end_score_rect1.height)) screen.blit(again_image, again_rect) screen.blit(gameover_image, gameover_rect) if life_num: # 绘制难度 level_text = level_font.render('level : %s' % str(level), True, white) screen.blit(level_text, (10, 50)) # 绘制暂停按钮 screen.blit(pause_image, pause_rect) # 绘制分数 score_text = score_font.render('Score : %d' % score, True, white) screen.blit(score_text, (10, 10)) delay -= 1 if not delay: delay = 1000 pygame.display.flip() # 帧数 clock.tick(60)
def main(): pygame.mixer.music.play(-1) # 这里参数-1是指无限循环播放bgm # 生成我方飞机,调用myplane模块的MyPlace实例化 # me =myplane.BluePlane(bg_size) me =myplane.MyPlane(bg_size) # me =myplane.RedPlane(bg_size) plane_color = 0 # 飞机变色标签 color_bullet=False # 飞机变色子弹变化 plane_image1=me.image1 plane_image2=me.image2 # 设置默认飞机图片 # 用于切换飞机尾气图片 switch_image=True # 用于延迟 delay=100 # 生成敌方飞机(将所有敌机放入碰撞组) 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=6 # 设置为四颗子弹(每屏幕) for i in range(BULLET1_NUM): bullet1.append(bullet.Bullet1(me.rect.midtop)) # rect的midtop即位于顶部中央 # 生成超级子弹 bullet2 = [] bullet2_index = 0 BULLET2_NUM = 12 # 设置为四颗子弹(每屏幕) 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))) # 生成懒羊羊子弹 bullet3=[] bullet3_index=0 BULLET3_NUM=6 for i in range(BULLET3_NUM): bullet3.append(bullet.Bullet3(me.rect.midtop)) # BGM切换标志 bgm_change=False # 用于统计得分 score=0 score_font=pygame.font.Font('font/font.ttf',36) # pyinstaller打包时字体要写绝对路径 # 暂停游戏标志 paused=False paused_nor_image=pygame.image.load(r'./images/pause_nor.png').convert_alpha() paused_pressed_image=pygame.image.load(r'./images/pause_pressed.png').convert_alpha() resume_nor_image=pygame.image.load(r'./images/resume_nor.png').convert_alpha() resume_pressed_image=pygame.image.load(r'./images/resume_pressed.png').convert_alpha() paused_rect=paused_nor_image.get_rect() paused_rect.left,paused_rect.top=width-paused_rect.width-10,10 paused_image=paused_nor_image # 设置暂停默认图片款式 # 设置难度级别 level=1 # 设置全屏炸弹 bomb_image=pygame.image.load(r'./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.Bullet_Supply(bg_size) bomb_supply=supply.Bomb_Supply(bg_size) sun_supply=supply.Sun_Supply(bg_size) # 补给包定时器(自定义事件) 30s SUPPLY_TIMER=USEREVENT pygame.time.set_timer(SUPPLY_TIMER,20*1000) # 超级子弹定时器 DOUBLE_BULLET_TIMER=USEREVENT+1 # 标志是否使用 is_double_bullet=False # 懒羊羊变身定时器 SHEEP_TIMER=USEREVENT+2 # 标志是否变身 is_sheep=False # 解除我方无敌计时器 INVINCIBLE_TIMER=USEREVENT+3 # 生命剩余 life_image=pygame.image.load('images/life.png').convert_alpha() life_rect=life_image.get_rect() life_num=3 # 用于阻止重复打开记录文件 recorded=False # 游戏结束画面 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() # 中弹图片索引(中弹图片切换特效) e1_destroy_index=0 e2_destroy_index=0 e3_destroy_index=0 me_destroy_index=0 clock=pygame.time.Clock() running=True while running: # 偶尔发生的用event事件来描述即可 for event in pygame.event.get(): if event.type==pygame.QUIT: pygame.quit() sys.exit() elif event.type==pygame.MOUSEBUTTONDOWN: if event.button==1 and paused_rect.collidepoint(event.pos): # rect的collidepoint方法检测事件是否发生的矩形区域内 paused=not paused if paused: # 暂停时音乐和音效暂停 pygame.mixer.music.pause() pygame.mixer.pause() else: # 音乐和音效继续播放 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=paused_pressed_image else: if paused: paused_image=resume_nor_image else: paused_image=paused_nor_image elif event.type==KEYDOWN and not paused: if event.key==K_SPACE: if bomb_num: bomb_num-=1 thunder_sound.play() screen.blit(thunder_image,(0,0)) pygame.display.flip() pygame.time.delay(700) for each in enemies: if each.rect.bottom>0: each.active=False # 添加飞机变色 if event.key==K_j or event.key==K_k: plane_color+=1 color_bullet=True elif event.type==SUPPLY_TIMER and not paused: supply_sound.play() supply_choice=choice([0,1,2]) if supply_choice==0: bomb_supply.reset() elif supply_choice==1: bullet_supply.reset() elif supply_choice==2: sun_supply.reset() elif event.type==DOUBLE_BULLET_TIMER: # 触发超级子弹18秒后启动DOUBLE_BULLET_TIMER事件,定时器就关闭 is_double_bullet=False pygame.time.set_timer(DOUBLE_BULLET_TIMER,0) elif event.type==SHEEP_TIMER: is_sheep=False pygame.time.set_timer(SHEEP_TIMER,0) color_bullet = True # 变身懒羊羊结束后,需要变回普通形态 elif event.type==INVINCIBLE_TIMER: me.invincible=False pygame.time.set_timer(INVINCIBLE_TIMER,0) # 触发解除无敌事件后,取消计时器 # 根据用户得分增加难度 if level==1 and score >500: level=2 upgrade_sound.play() # 增加三架小飞机,两架中飞机,一架大飞机 add_small_enemies(small_enemies,enemies,3) add_mid_enemies(mid_enemies,enemies,2) add_big_enemies(big_enemies,enemies,1) # 提升小飞机速度(1点) increase_speed(small_enemies,1) elif level==2 and score>2000: level=3 upgrade_sound.play() # 增加三架小飞机,两架中飞机,一架大飞机 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) increase_speed(mid_enemies, 1) elif level==3 and score>8000: level = 4 upgrade_sound.play() # 增加三架小飞机,两架中飞机,一架大飞机 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) increase_speed(mid_enemies, 1) elif level == 4 and score > 15000: level = 5 upgrade_sound.play() # 增加三架小飞机,两架中飞机,一架大飞机 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) bgm_change = True # 切歌 if bgm_change: pygame.mixer.music.load(r'sound/all.ogg') pygame.mixer.music.set_volume(0.15) pygame.mixer.music.play(-1) bgm_change=False # 背景绘制 screen.blit(background, (0, 0)) if life_num and not paused: # 频繁发生的用key模块 检测用户的整个键盘操作,返回布尔类型值 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() # 绘制炸弹补给包并检测获得 if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image,bomb_supply.rect) if pygame.sprite.collide_mask(me,bomb_supply): # 这里检测完美碰撞(两个单体),返回True和False 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(me, bullet_supply): # 这里检测完美碰撞(两个单体),返回True和False get_bullet_sound.play() # 发射超级子弹,持续18秒 is_double_bullet=True pygame.time.set_timer(DOUBLE_BULLET_TIMER,12*1000) bullet_supply.active=False # 绘制太阳补给包并检测获得 if sun_supply.active: sun_supply.move() screen.blit(sun_supply.image, sun_supply.rect) if pygame.sprite.collide_mask(me, sun_supply): # 这里检测完美碰撞(两个单体),返回True和False is_sheep=True pygame.time.set_timer(SHEEP_TIMER,5*1000) sun_supply.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) # 在飞机上方五个像素位置画一条线(宽2像素) # 当生命大于20%显示绿色,否则显示红色 energy_remanin=each.energy/enemy.BigEnemy.energy if energy_remanin>0.2: energy_color=GREEN else: energy_color=RED pygame.draw.line(screen,energy_color,(int(each.rect.left),int(each.rect.top-5)), (int(each.rect.left)+int(each.rect.width*energy_remanin),int(each.rect.top-5)),2) # 绘制生命剩余 # 大飞机即将出现时带音效 if each.rect.bottom==-50: # 大飞机speed=1,肯定会到达-50,这时候开始播放(知道挂掉) enemy3_fly_sound.play(-1) # -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) # 下面是个小技巧,余数从0~5,对应毁灭图片列表里6歌元素 e3_destroy_index=(e3_destroy_index+1)%6 # 一开始(0+1)%6==1 ,下面判断确保进行一轮 if e3_destroy_index==0: enemy3_fly_sound.stop() score+=1000 each.reset() # 绘制中飞机 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) # 绘制血槽 pygame.draw.line(screen, BLACK, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) # 在飞机上方五个像素位置画一条线(宽2像素) # 当生命大于20%显示绿色,否则显示红色 energy_remanin = each.energy / enemy.MidEnemy.energy if energy_remanin > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, (int(each.rect.left), int(each.rect.top - 5)), (int(each.rect.left + each.rect.width * energy_remanin), int(each.rect.top - 5)), 2) # 绘制生命剩余 else: if not (delay % 3): # 降速否则毁灭图片看不清 if e2_destroy_index == 0: # 毁灭之歌 enemy2_down_sound.play() # 防止pygame音效通道被占满(防止重复帧播放音效) # 毁灭时放图片(索引) screen.blit(each.destroy_images[e2_destroy_index],each.rect) # 下面是个小技巧,余数从0~5,对应毁灭图片列表里6歌元素 e2_destroy_index=(e2_destroy_index+1)%4 # 一开始(0+1)%6==1 ,下面判断确保进行一轮 if e2_destroy_index==0: score+=500 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) # 下面是个小技巧,余数从0~5,对应毁灭图片列表里6歌元素 e1_destroy_index=(e1_destroy_index+1)%4 # 一开始(0+1)%6==1 ,下面判断确保进行一轮 if e1_destroy_index==0: score+=100 each.reset() # 子弹发射(每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 elif is_sheep: bullets=bullet3 bullets[bullet3_index].reset((me.rect.left,me.rect.top)) bullet3_index=(bullet3_index+1)%BULLET3_NUM else: bullets=bullet1 bullets[bullet1_index].reset(me.rect.midtop) # 这里其实是预算了子弹差不多4颗能到屏幕80%地方(飞机下面状态栏占了20%) 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: # 中飞机和大飞机血量为0才阵亡 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 #检测我方飞机是否被撞(第三个参数是碰撞毁灭False,第四个参数默认是矩形区域检测)) enemies_down=pygame.sprite.spritecollide(me,enemies,False,pygame.sprite.collide_mask) # pygame.sprite.collide_mask图片非透明部分接触碰撞 if enemies_down and not me.invincible: me.active=False # 返回一个列表,里面包含所有与sprite碰撞的元素,敌机的active也为False for e in enemies_down: e.active=False # 我方飞机颜色转换绘制及子弹数量不同设置 if me.active: if is_sheep: plane_image1=me.image1_sheep plane_image2=me.image1_sheep else: if color_bullet: if plane_color==0 or plane_color==3: plane_image1=me.image1 plane_image2=me.image2 # BULLET1_NUM = 6 # BULLET2_NUM = 12 # bullet1.append(bullet.Bullet1(me.rect.midtop)) # bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery))) # bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery))) for i in bullet1: i.speed=12 for j in bullet2: j.speed=12 me.speed=10 elif plane_color==1: plane_image1=me.image1_r plane_image2=me.image2_r # BULLET1_NUM = 7 # BULLET2_NUM = 14 # bullet1.append(bullet.Bullet1(me.rect.midtop)) # bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery))) # bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery))) for i in bullet1: i.speed=20 for j in bullet2: j.speed=20 me.speed=7 elif plane_color==2: plane_image1=me.image1_b plane_image2=me.image2_b # BULLET1_NUM = 5 # BULLET2_NUM = 10 # bullet1.remove(bullet1[-1]) # bullet1.remove(bullet1[-1]) # bullet2.remove(bullet2[-1]) # bullet2.remove(bullet2[-1]) # bullet2.remove(bullet2[-1]) # bullet2.remove(bullet2[-1]) for i in bullet1: i.speed=9 for j in bullet2: j.speed=9 me.speed=14 color_bullet=False # 我方飞机绘制(尾气切换) if switch_image: screen.blit(plane_image1,me.rect) else: screen.blit(plane_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) # 下面是个小技巧,余数从0~5,对应毁灭图片列表里6歌元素 me_destroy_index = (me_destroy_index + 1) % 4 # 一开始(0+1)%6==1 ,下面判断确保进行一轮 if me_destroy_index == 0: # me.reset() life_num-=1 me.reset() pygame.time.set_timer(INVINCIBLE_TIMER,3*1000) # 设置reset后3秒,然后启动解除无敌状态 # 得分显示(render函数将成字符串渲染成surface对象) score_text = score_font.render("Score : %s" % str(score), True, BLUE) # 第二个参数为True表示拒绝锯齿 screen.blit(score_text, (10, 5)) # 生命为0结束 elif life_num==0: # bgm停止 pygame.mixer.music.stop() # 停止音效 pygame.mixer.stop() # 停止补给包 pygame.time.set_timer(SUPPLY_TIMER,0) if not recorded: # 读取历史最高分 with open("record.txt",'a+')as f: f.seek(0,0) record_score=int(f.read()) # 如果玩家得分高于最高分则存档 if score>record_score: f.seek(0, 0) f.truncate() f.write(str(score)) recorded=True print("Game Over!") # 绘制游戏结束画面 record_score_text=score_font.render("Best : %d"%record_score,True,BLUE) 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//3 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) # 检测用户的鼠标操作 # 如果用户按下鼠标左键(0表示第一个元素————鼠标左键) 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 gameover_rect.left < pos[0] < gameover_rect.right and \ gameover_rect.top < pos[1] < gameover_rect.bottom: # 退出游戏 pygame.quit() sys.exit() # 绘制暂停按钮 screen.blit(paused_image,paused_rect) # 绘制清屏炸弹显示 # 炸弹图片 screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) # 炸弹文本 bomb_text=bomb_font.render("x %d"%bomb_num,True,WHITE) text_rect=bomb_text.get_rect() screen.blit(bomb_text,(20+bomb_rect.width,height-5-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)) # 延迟切换(delay只有被5整除的时候才会切换) if not(delay%5): switch_image = not switch_image delay-=1 if not delay: delay=100 # 相当于60帧的游戏尾气切换只有12帧 # 颜色切换 if plane_color==3: plane_color=0 pygame.display.flip() clock.tick(60)
def main(): # 循环播放背景音乐 pygame.mixer.music.play(-1) # 生成我方飞机 me = myplane.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))) # 初始化四层子弹 bullet3 = [] bullet3_index = 0 bullet3_num = 16 for i in range(bullet3_num // 4): bullet3.append(bullet.Bullet3((me.rect.centerx - 63, me.rect.centery))) bullet3.append(bullet.Bullet3((me.rect.centerx - 23, me.rect.centery))) bullet3.append(bullet.Bullet3((me.rect.centerx + 23, me.rect.centery))) bullet3.append(bullet.Bullet3((me.rect.centerx + 63, me.rect.centery))) # 初始化延时器 clock = pygame.time.Clock() # 定义绘制飞机索引 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) # 初始化暂停按钮和状态 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() paused_rect = pause_nor_image.get_rect() paused_rect.left,paused_rect.top = width - paused_rect.width - 10,10 paused_image = pause_nor_image # 初始化禁音按钮和状态 silence = False volume_on_pressed_image = pygame.image.load('images/sound_open.png').convert_alpha() volume_on_image = pygame.image.load('images/sound_open_not.png').convert_alpha() volume_off_pressed_image = pygame.image.load('images/sound_close.png').convert_alpha() volume_off_image = pygame.image.load('images/sound_close_not.png').convert_alpha() volume_rect = volume_on_image.get_rect() volume_rect.left, volume_rect.top = width - paused_rect.width - 10, 65 volume_image = volume_on_image # 初始化等级 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 # 初始化补给 bullet_supply = supply.Bullet_Supply(bg_size) bomb_supply = supply.Bomb_Supply(bg_size) heart_supply = supply.Heart_Supply(bg_size) ice_supply = supply.Ice_Supply(bg_size) fire_supply = supply.Fire_Supply(bg_size) SUPPLY_TIME = USEREVENT pygame.time.set_timer(SUPPLY_TIME,30 * 1000) DOUBLE_BULLET_TIME = USEREVENT + 1 is_double_bullet = False is_super_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 # 避免反复读取文件 recorded = False # 初始化游戏结束元素 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() flozen = False FLOZEN_TIME = USEREVENT + 3 bg_posy = -700 switch_image = True delay = 100 running = True while running: for event in pygame.event.get(): if event.type == 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() elif not paused and not silence: # 设置发放补给 pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) # 继续播放音乐 pygame.mixer.music.unpause() pygame.mixer.unpause() if event.button == 1 and volume_rect.collidepoint(event.pos): silence = not silence if silence: pygame.mixer.music.pause() pygame.mixer.pause() elif not paused and not silence: 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 # 如果用户点击了禁音按钮 if volume_rect.collidepoint(event.pos): if silence: volume_image = volume_off_pressed_image else: volume_image = volume_on_pressed_image else: if silence: volume_image = volume_off_image else: volume_image = volume_on_image elif event.type == KEYDOWN: # 用户使用了全屏炸弹 if event.key == K_SPACE: if bomb_num: bomb_num -= 1 if not silence: bomb_sound.play() for each in enemies: if each.rect.bottom > 0: each.active = False elif event.type == SUPPLY_TIME: # 发放补给 if not silence: supply_sound.play() # 随机的补给内容 choose = choice([1,2,3,4,5]) if choose == 1: bomb_supply.reset() elif choose == 2: bullet_supply.reset() elif choose == 3: fire_supply.reset() elif choose == 4: ice_supply.reset() elif choose == 5: heart_supply.reset() elif event.type == DOUBLE_BULLET_TIME: # 结束超级子弹的使用 is_double_bullet = False is_super_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) elif event.type == FLOZEN_TIME: if not silence: lose_ice_sound.play() flozen = False pygame.time.set_timer(FLOZEN_TIME, 0) # 级别上升 if level == 1 and score > 50000: level = 2 if not silence: upgrade_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 == 1 and score > 300000: level = 2 if not silence: upgrade_sound.play() 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 if not silence: upgrade_sound.play() 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 if not silence: upgrade_sound.play() 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) # 绘制背景 if bg_posy >= 0 and not paused and not flozen: bg_posy = -700 if not paused and not flozen: bg_posy += 0.5 screen.blit(background, (0, bg_posy)) if life_num and not paused: if not flozen: 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() if bomb_supply.active: bomb_supply.move() screen.blit(bomb_supply.image, bomb_supply.rect) if pygame.sprite.collide_mask(bomb_supply, me): if not silence: 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): if not silence: get_bullet_sound.play() is_double_bullet = True pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000) bullet_supply.active = False if heart_supply.active: heart_supply.move() screen.blit(heart_supply.image, heart_supply.rect) if pygame.sprite.collide_mask(heart_supply, me): if not silence: get_heart_sound.play() if life_num < 3 and life_num > 0: life_num += 1 heart_supply.active = False if ice_supply.active: ice_supply.move() screen.blit(ice_supply.image, ice_supply.rect) if pygame.sprite.collide_mask(ice_supply, me): if not silence: get_ice_sound.play() pygame.time.set_timer(FLOZEN_TIME, 5 * 1000) flozen = True ice_supply.active = False if fire_supply.active: fire_supply.move() screen.blit(fire_supply.image, fire_supply.rect) if pygame.sprite.collide_mask(fire_supply, me): if not silence: get_bullet_sound.play() is_super_bullet = True pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000) fire_supply.active = False if not(delay % 10) and not flozen: if not silence: 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 elif is_super_bullet: bullets = bullet3 bullets[bullet3_index].reset((me.rect.centerx - 63, me.rect.centery)) bullets[bullet3_index + 1].reset((me.rect.centerx - 23, me.rect.centery)) bullets[bullet3_index + 2].reset((me.rect.centerx + 23, me.rect.centery)) bullets[bullet3_index + 3].reset((me.rect.centerx + 63, me.rect.centery)) bullet3_index = (bullet3_index + 4) % bullet3_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 and not flozen: 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(flozen) 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.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 and not silence: enemy3_fly_sound.play(-1) else: if not (delay % 3): if e3_destroy_index == 0 and not silence: 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(flozen) 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) 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 and not silence: 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(flozen) screen.blit(each.image,each.rect) else: if not (delay % 3): if e1_destroy_index == 0 and not silence: 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 not me.invincible: if delay // 5 % 2 and not flozen: screen.blit(me.image1, me.rect) else: screen.blit(me.image2, me.rect) else: if delay % 10 < 7: screen.blit(me.image1, me.rect) else: if not silence: 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) if flozen: screen.blit(ice_bg,(0,0)) 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)) 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 == 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)) gameover_text1 = gameover_font.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 = gameover_font.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) 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) 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() screen.blit(paused_image,paused_rect) screen.blit(volume_image, volume_rect) if not(delay % 5): switch_image = not switch_image delay -= 1 if not delay: delay = 100 pygame.display.flip() clock.tick(60)