Beispiel #1
0
def main(USER):
    pygame.init()
    pygame.mixer.init()

    bg_size = width, height = 480, 700
    screen = pygame.display.set_mode(bg_size)
    pygame.display.set_caption('Plane War')

    # background = pygame.image.load(MAINFILE_PATH + 'images/img_bg_level_1.jpg').convert()

    # 定义颜色
    BLACK = (0, 0, 0)
    GREEN = (0, 255, 0)
    RED = (255, 0, 0)
    WHITE = (255, 255, 255)

    # 载入音乐
    pygame.mixer.music.load(MAINFILE_PATH + 'sound/hundouluo.wav')
    pygame.mixer.music.set_volume(0.2)

    bullet_sound = pygame.mixer.Sound(MAINFILE_PATH + 'sound/bullet.wav')
    bullet_sound.set_volume(0.2)

    bomb_sound = pygame.mixer.Sound(MAINFILE_PATH + 'sound/use_bomb.wav')
    bomb_sound.set_volume(0.2)

    supply_sound = pygame.mixer.Sound(MAINFILE_PATH + 'sound/supply.wav')
    supply_sound.set_volume(0.2)

    get_bomb_sound = pygame.mixer.Sound(MAINFILE_PATH + 'sound/get_bomb.wav')
    get_bomb_sound.set_volume(0.2)

    get_bullet_sound = pygame.mixer.Sound(MAINFILE_PATH +
                                          'sound/get_bullet.wav')
    get_bullet_sound.set_volume(0.2)

    upgrade_sound = pygame.mixer.Sound(MAINFILE_PATH + 'sound/upgrade.wav')
    upgrade_sound.set_volume(0.2)

    enemy3_fly_sound = pygame.mixer.Sound(MAINFILE_PATH +
                                          'sound/enemy3_flying.wav')
    enemy3_fly_sound.set_volume(0.6)

    enemy1_down_sound = pygame.mixer.Sound(MAINFILE_PATH +
                                           'sound/enemy1_down.wav')
    enemy1_down_sound.set_volume(0.2)

    enemy2_down_sound = pygame.mixer.Sound(MAINFILE_PATH +
                                           'sound/enemy2_down.wav')
    enemy2_down_sound.set_volume(0.2)

    enemy3_down_sound = pygame.mixer.Sound(MAINFILE_PATH +
                                           'sound/enemy3_down.wav')
    enemy3_down_sound.set_volume(0.2)

    me_down_sound = pygame.mixer.Sound(MAINFILE_PATH + 'sound/me_down.wav')
    me_down_sound.set_volume(0.2)

    def add_small_enemies(group1, group2, num):
        for i in range(num):
            e1 = enemy.SmallEnemy(bg_size)
            group1.add(e1)
            group2.add(e1)

    def add_mid_enemies(group1, group2, num):
        for i in range(num):
            e2 = enemy.MidEnemy(bg_size)
            group1.add(e2)
            group2.add(e2)

    def add_big_enemies(group1, group2, num):
        for i in range(num):
            e3 = enemy.BigEnemy(bg_size)
            group1.add(e3)
            group2.add(e3)

    def inc_speed(target, inc):
        for each in target:
            each.speed += inc

    def add_background(background_image, screen):
        bg1 = Background(background_image, screen)
        bg2 = Background(background_image, screen, True)
        background_group = pygame.sprite.Group(bg1, bg2)
        return background_group

    # 播放音乐
    pygame.mixer.music.play(-1)

    # 第一关背景
    background_group = add_background(
        MAINFILE_PATH + 'images/img_bg_level_1.jpg', screen)
    # 关卡锁
    level_2 = False
    level_3 = False
    level_4 = False
    level_5 = False

    # 实例我方飞机
    me = myplane.MyPlane(bg_size=bg_size)

    # 实例敌方飞机
    enemies = pygame.sprite.Group()

    # 实例敌方小型飞机
    small_enemies = pygame.sprite.Group()
    add_small_enemies(small_enemies, enemies, 10)

    # 实例敌方中型飞机
    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.centerx - 10, me.rect.centery), screen))

    # 实例超级子弹
    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), screen))
        bullet2.append(
            bullet.Bullet2((me.rect.centerx + 30, me.rect.centery), screen))

    # 中弹图片索引
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    me_destroy_index = 0

    # 统计得分
    score = 0
    score_font = pygame.font.Font(MAINFILE_PATH + "font/rough.ttf", 36)

    # 标志是否暂停游戏
    paused = False
    paused_nor_image = pygame.image.load(
        MAINFILE_PATH + "images/pause_nor.png").convert_alpha()
    paused_pressed_image = pygame.image.load(
        MAINFILE_PATH + "images/pause_pressed.png").convert_alpha()
    resume_nor_image = pygame.image.load(
        MAINFILE_PATH + 'images/resume_nor.png').convert_alpha()
    resume_pressed_image = pygame.image.load(
        MAINFILE_PATH + '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(MAINFILE_PATH +
                                   'images/bomb.png').convert_alpha()
    bomb_rect = bomb_image.get_rect()
    bomb_font = pygame.font.Font(MAINFILE_PATH + "font/font.ttf", 48)
    bomb_num = 3

    # 每30秒发放一个补给包
    bullet_supply = supply.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)

    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 15 * 1000)

    # 超级子弹定时器
    DOUBLE_BULLTET_TIME = USEREVENT + 1

    # 解除我方重生无敌定时器
    INVINCIBLE_TIME = USEREVENT + 2

    # 标志是否使用超级子弹
    is_double_bullet = False

    # 生命数量
    life_image = pygame.image.load(MAINFILE_PATH +
                                   'images/My_plane.png').convert_alpha()
    life_width, life_height = life_image.get_size()
    life_width, life_height = life_width // 4, life_height // 4
    life_image = pygame.transform.smoothscale(life_image,
                                              (life_width, life_height))
    life_rect = life_image.get_rect()
    life_num = 3

    # 游戏结束画面
    gameover_font = pygame.font.Font(MAINFILE_PATH + "font/font.TTF", 48)
    again_image = pygame.image.load(MAINFILE_PATH +
                                    "images/again.png").convert_alpha()
    again_rect = again_image.get_rect()
    gameover_image = pygame.image.load(MAINFILE_PATH +
                                       "images/gameexit.png").convert_alpha()
    gameover_rect = gameover_image.get_rect()

    # 用于延迟切换
    delay = 100

    # 限制打开一次记录文件
    recorded = False

    clock = pygame.time.Clock()
    running = True

    while running:
        if not pygame.display.get_active():
            paused = True
            pygame.time.set_timer(SUPPLY_TIME, 0)
            pygame.mixer.music.pause()
            pygame.mixer.pause()

        # if pygame.display.get_active():
        #     paused = False
        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, 15 * 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 = paused_pressed_image
                else:
                    if paused:
                        paused_image = resume_nor_image
                    else:
                        paused_image = paused_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.key == K_p:
                    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, 15 * 1000)
                        pygame.mixer.music.unpause()
                        pygame.mixer.unpause()
                elif event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()

            elif event.type == SUPPLY_TIME:
                supply_sound.play()
                if choice([True, False]):
                    bomb_supply.reset()
                else:
                    bullet_supply.reset()

            elif event.type == DOUBLE_BULLTET_TIME:
                is_double_bullet = False
                pygame.time.set_timer(DOUBLE_BULLTET_TIME, 0)

            elif event.type == INVINCIBLE_TIME:
                me.invincible = False
                pygame.time.set_timer(INVINCIBLE_TIME, 0)

        # 根据用户得分增加难度
        if level == 1 and score > 1000:
            level = 2
            if not level_2:
                background_group.empty()
                background_group = add_background(
                    MAINFILE_PATH + 'images/img_bg_level_2.jpg', screen)
                level_2 = True
            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(target=small_enemies, inc=1)

        elif level == 2 and score > 3000:
            level = 3
            if not level_3:
                background_group.empty()
                background_group = add_background(
                    MAINFILE_PATH + 'images/img_bg_level_3.jpg', screen)
                level_3 = True
            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(target=small_enemies, inc=1)
            inc_speed(target=mid_enemies, inc=1)

        elif level == 3 and score > 10000:
            level = 4
            if not level_4:
                background_group.empty()
                background_group = add_background(
                    MAINFILE_PATH + 'images/img_bg_level_4.jpg', screen)
                level_4 = True

            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(target=small_enemies, inc=1)
            inc_speed(target=mid_enemies, inc=1)

        elif level == 4 and score > 20000:
            level = 5
            if not level_5:
                background_group.empty()
                background_group = add_background(
                    MAINFILE_PATH + 'images/img_bg_level_5.jpg', screen)
                level_5 = True

            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(target=small_enemies, inc=1)
            inc_speed(target=mid_enemies, inc=1)
            inc_speed(target=big_enemies, inc=1)

        # screen.blit(background, (0, 0))
        background_group.update()
        background_group.draw(screen)

        if life_num 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()
            # if key_pressed[K_p]:
            #     paused = not paused
            #     pygame.time.set_timer(SUPPLY_TIME, 0)
            #     pygame.mixer.music.pause()
            #     pygame.mixer.pause()
            # 绘制全屏炸弹补给
            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 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()
                    # 发射超级子弹
                    is_double_bullet = True
                    pygame.time.set_timer(DOUBLE_BULLTET_TIME, 8 * 1000)
                    bullet_supply.active = False

            # 发射子弹
            if not (delay % 16):
                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.centerx - 10, me.rect.centery))
                    bullet1_index = (bullet1_index + 1) % BULLET1_NUM

                # 检测子弹是否击中敌机
            try:
                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 each in enemy_hit:
                                each.hit = True
                                each.energy -= 1
                                if each.energy == 0:
                                    each.active = False
            except:
                pass
            # 绘制敌方大型机
            for each in big_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)

                    # 当生命大于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 == -10:
                        enemy3_fly_sound.play(-1)
                        each.appear = True
                    # 离开画面, 关闭音效
                    if each.rect.bottom < -10 and each.appear:
                        enemy3_fly_sound.stop()
                        each.appear = False
                else:
                    # 毁灭
                    if e3_destroy_index == 0:
                        enemy3_down_sound.play()
                    if not (delay % 2):
                        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 += 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)

                    # 当生命大于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 e2_destroy_index == 0:
                        enemy2_down_sound.play()
                    if not (delay % 2):
                        screen.blit(each.destroy_images[e2_destroy_index],
                                    each.rect)
                        e2_destroy_index = (e2_destroy_index + 1) % 4
                        if e2_destroy_index == 0:
                            score += 600
                            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 % 2):
                        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()

            # 检测我方飞机碰撞
            enemies_down = pygame.sprite.spritecollide(
                me, enemies, False, pygame.sprite.collide_mask)
            if enemies_down and not me.invincible:
                me.active = False
                for each in enemies_down:
                    each.active = False

            # 绘制我方飞机
            if me.active:
                screen.blit(me.image, me.rect)

            else:
                # 毁灭
                if me_destroy_index == 0:
                    me_down_sound.play()
                if not (delay % 2):
                    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)
            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 : %d' % score, True, WHITE)
            screen.blit(score_text, (10, 5))

        # elif life_num and paused:
        #     key_pressed = pygame.key.get_pressed()
        #     if key_pressed[K_p]:
        #         paused = not paused
        #         pygame.time.set_timer(SUPPLY_TIME, 15 * 1000)
        #         pygame.mixer.music.unpause()
        #         pygame.mixer.unpause()

        #  绘制游戏结束画面
        elif life_num == 0:
            # 背景音乐停止
            pygame.mixer.music.stop()

            # 停止全部音效
            pygame.mixer.stop()

            # 停止发放补给
            pygame.time.set_timer(SUPPLY_TIME, 0)

            if not recorded:
                recorded = True
                # 读取历史最高分
                try:
                    with open('record.txt', 'r') as f:
                        record = f.read()
                        record_user = record.split(',')[0]
                        record_score = int(record.split(',')[1])
                    # 判断是否高于历史最高分
                    if score > record_score:
                        with open('record.txt', 'w') as f:
                            f.write(USER + "," + str(score))
                            record_score = score
                            record_user = USER
                except:
                    with open('record.txt', 'w') as f:
                        f.write(USER + "," + str(score))
                        record_score = score
                        record_user = USER

            # 绘制结束界面
            record_score_text = score_font.render("Best : %d" % record_score,
                                                  True, (255, 255, 255))
            screen.blit(record_score_text, (50, 50))

            record_user_text = score_font.render("User : %s" % record_user,
                                                 True, (255, 255, 255))
            screen.blit(record_user_text, (200, 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(USER)
                # 如果用户点击“结束游戏”
                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)

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Beispiel #2
0
def main():
    # -----------------------------------
    # 背景音乐持续播放
    pygame.mixer.music.play(-1)

    # 生成我方飞机
    me = heroplane.HeroPlane(bg_size)

    enemies = pygame.sprite.Group()

    # 生成敌方小型飞机
    small_enemies = pygame.sprite.Group()
    add_small_enemies(small_enemies, enemies, 10)

    # 生成敌方中型飞机
    mid_enemies = pygame.sprite.Group()
    add_mid_enemies(mid_enemies, enemies, 3)

    # 生成敌方大型飞机
    big_enemies = pygame.sprite.Group()
    add_big_enemies(big_enemies, enemies, 2)

    # 生成敌方特殊飞机
    plus_enemies = enemy.PlusEnemy(bg_size)

    # 生成普通子弹
    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 = 21
    for i in range(BULLET3_NUM // 2):
        bullet3.append(bullet.Bullet2((me.rect.centerx - 30, me.rect.centery)))
        bullet3.append(bullet.Bullet2((me.rect.centerx - 00, me.rect.centery)))
        bullet3.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery)))

    # 生成敌方 子弹
    bullet4 = []
    bullet4_index = 0
    BULLET4_NUM = 20
    for i in range(BULLET4_NUM):
        bullet4.append(bullet.Bullet_enemy(plus_enemies.rect.midbottom))

    clock = pygame.time.Clock()

    # 中弹图片索引
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    e4_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

    # 标志开始游戏
    # start_flag = False
    # start_flag_pressed_image = pygame.image.load(
    #     "images/resume_nor.png").convert_alpha()
    # start_rect = start_flag_pressed_image.get_rect()

    # 设置难度级别
    level = 1
    Level_MAX_Flag = False

    # 全屏炸弹
    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 = 1000
    MAX_BOMB_NUM = 1000

    # 初始每30秒发放一个补给包
    # 随着关卡难度上升补给时间间隔缩短
    # 基本单位设置为毫秒级别,不建议把时间设置的太低
    Invincible_supply = supply.Invincible_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    supply_Inset_time = 30
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, supply_Inset_time * 1000)

    # 超级子弹定时器
    DOUBLE_BULLET_TIME = USEREVENT + 1

    # 标志是否使用超级子弹
    is_double_bullet = False
    is_thirh_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
    MAX_LIFE_NUM = 3

    # 用于阻止重复打开记录文件
    recorded = False

    # 游戏结束画面
    gameover_flag = 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

    # 游戏进行时间计时
    Time_Running_Count = time.time()

    # 用于延迟
    delay = 100

    running = True
    """
    Game Start
    """

    while running:
        y1, y2 = bg_update()

        # pygame.event.get() 从队列中获取事件
        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, 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

                # b键 自爆清屏
                elif event.key == K_b:
                    me.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_sound.play()
                        for each in enemies:
                            if each.rect.bottom > 0:
                                each.active = False

                # Q键 暂停
                elif event.key == K_q:
                    if paused:
                        paused_image = resume_pressed_image
                    else:
                        paused_image = pause_pressed_image
                    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.key == K_1:
                    life_num = 0

            elif event.type == SUPPLY_TIME:
                supply_sound.play()
                if choice([True, False]):
                    bomb_supply.reset()
                else:
                    Invincible_supply.reset()
                # Invincible_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 and score >= 10000:
            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)
            life_num = gmplus.Life_plus(life_num, MAX_LIFE_NUM)
            supply_Inset_time -= 3

        elif level == 2 and score < 100000 and score >= 50000:
            level = 3
            upgrade_sound.play()
            # 增加5架小型敌机、3架中型敌机和2架大型敌机
            add_small_enemies(small_enemies, enemies, 4)
            add_mid_enemies(mid_enemies, enemies, 2)
            add_big_enemies(big_enemies, enemies, 1)
            # 提升小型敌机的速度
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)
            life_num = gmplus.Life_plus(life_num, MAX_LIFE_NUM)
            supply_Inset_time -= 3

        elif level == 3 and score < 200000 and score >= 100000:
            level = 4
            upgrade_sound.play()
            # 提升小型敌机的速度
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)
            life_num = gmplus.Life_plus(life_num, MAX_LIFE_NUM)
            supply_Inset_time -= 3

        elif level == 4 and (not Level_MAX_Flag) and score > 200000:
            level = 5
            Level_MAX_Flag = True
            upgrade_sound.play()
            # 提升小型敌机的速度
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)
            life_num = gmplus.Life_plus(life_num, MAX_LIFE_NUM)
            supply_Inset_time -= 3

        # 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.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):
                    get_bomb_sound.play()
                    if bomb_num < MAX_BOMB_NUM:
                        bomb_num += 2
                        if bomb_num > MAX_BOMB_NUM:
                            bomb_num = MAX_BOMB_NUM
                    bomb_supply.active = False

            # 无敌状态补给检测

            # 绘制无敌补给并检测是否获得
            if Invincible_supply.active:
                Invincible_supply.move()
                screen.blit(Invincible_supply.image, Invincible_supply.rect)
                if pygame.sprite.collide_mask(Invincible_supply, me):
                    get_bullet_sound.play()
                    # is_double_bullet = True
                    me.invincible = True
                    pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000)
                    Invincible_supply.active = False

            # 我方发射子弹
            # 发射子弹的类型变更判断
            if level < 5 and level >= 3:
                is_double_bullet = True
            elif level >= 5:
                is_double_bullet = False
                is_thirh_bullet = True

            # 发射子弹
            if not (delay % 10):
                bullet_sound.play()
                if is_thirh_bullet:
                    bullets = bullet3
                    bullets[bullet3_index].reset(
                        (me.rect.centerx - 33, me.rect.centery))
                    bullets[bullet3_index + 1].reset(
                        (me.rect.centerx - 00, me.rect.centery))
                    bullets[bullet3_index + 2].reset(
                        (me.rect.centerx + 30, me.rect.centery))
                    bullet3_index = (bullet3_index + 3) % BULLET3_NUM
                elif 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)

                    enemy_bullets_hit = pygame.sprite.collide_rect(
                        b, plus_enemies)
                    if enemy_bullets_hit:
                        b.active = False
                        plus_enemies.active = False

                    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

            # 敌方发射子弹
            if not (delay % 100):
                bullet_sound.play()
                bullets_enemy = bullet4
                bullets_enemy[bullet4_index].reset(plus_enemies.rect.midbottom)
                bullet4_index = (bullet4_index + 1) % BULLET4_NUM
                print("敌方子弹发射了")

            # 绘制大型敌机
            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 delay > 50:
                        each.moveRight()
                    else:
                        each.moveLeft()

                    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()

                    if delay > 50:
                        each.moveLeft()
                    else:
                        each.moveRight()

                    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()

            # 绘制特殊敌机:
            if plus_enemies.active:
                plus_enemies.move()
                screen.blit(plus_enemies.image, plus_enemies.rect)
            else:
                # 毁灭
                print("消灭了")
                if not (delay % 3):
                    if e4_destroy_index == 0:
                        enemy1_down_sound.play()
                    screen.blit(plus_enemies.destroy_images[e4_destroy_index],
                                plus_enemies.rect)
                    e4_destroy_index = (e4_destroy_index + 1) % 4
                    if e4_destroy_index == 0:
                        print("加分了")
                        score += 3000
                        plus_enemies.reset()

            # 检测敌军子弹是否击中友军飞机
            for b in bullets_enemy:
                if b.active:
                    b.move()
                    screen.blit(b.image, b.rect)
                    enemy_bullets_hit = pygame.sprite.collide_rect(b, me)
                    if enemy_bullets_hit and not me.invincible:
                        me.active = False
                        b.active = False

            # 敌机间的碰撞检测
            for each_a in enemies:
                for each_b in enemies:
                    if each_a != each_b:
                        enemies_Collide = pygame.sprite.collide_rect(
                            each_a, each_b)
                        if enemies_Collide:
                            if each_a.rect.left < each_b.rect.left:
                                each_a.rect.left -= 10
                                each_b.rect.left += 10
                            else:
                                each_a.rect.left += 10
                                each_b.rect.left -= 10

            # 检测我方飞机是否被撞
            enemies_down = pygame.sprite.spritecollide(
                me, enemies, False, pygame.sprite.collide_mask)
            enemies_plus_enemies = pygame.sprite.collide_rect(me, plus_enemies)

            if enemies_plus_enemies and not me.invincible:
                me.active = False
                plus_enemies.active = False

            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)
            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)
            level_text = score_font.render("level : %s" % str(level), True,
                                           WHITE)
            small_size_text = score_font.render(
                "Small_Size : %s" % str(len(small_enemies)), True, WHITE)
            mid_size_text = score_font.render(
                "Mid_Size : %s" % str(len(mid_enemies)), True, WHITE)
            big_size_text = score_font.render(
                "Big_Size : %s" % str(len(big_enemies)), True, WHITE)
            screen.blit(score_text, (10, 5))
            screen.blit(level_text, (10, 45))
            screen.blit(small_size_text, (10, 85))
            screen.blit(mid_size_text, (10, 125))
            screen.blit(big_size_text, (10, 165))

        # 绘制游戏结束画面
        elif life_num == 0:
            # Time_Ending_Count = time.time()

            # 部分变量初始化
            level = 1
            supply_Inset_time = 30

            gameover_flag = True
            # 背景音乐停止
            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" % max(record_score, 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函数,重新开始游戏
                    # gameover_flag = False
                    main()
                # 如果用户点击“结束游戏”
                elif gameover_rect.left < pos[0] < gameover_rect.right and \
                        gameover_rect.top < pos[1] < gameover_rect.bottom:
                    # 退出游戏
                    pygame.quit()
                    sys.exit()

        # 绘制暂停按钮
        if (not gameover_flag):
            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)
Beispiel #3
0
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
Beispiel #4
0
def main():
    pygame.mixer.music.play(-1)

    clock = pygame.time.Clock()

    # 中弹图片索引
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    me_destroy_index = 0

    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, 5)

    big_enemies = pygame.sprite.Group()
    add_big_enemies(big_enemies, enemies, 1)

    running = True
    switch_image = True
    delay = 100
    score = 0
    score_font = pygame.font.Font("font/font.ttf", 36)

    bullets = []

    # 生成普通子弹
    bullet1 = []
    bullet1_index = 0
    BULLET1_NUM = 5
    for i in range(BULLET1_NUM):
        bullet1.append(bullet.Bullet1(me.rect.midtop))

    # 生命数量
    life_image = pygame.image.load("images/life.png").convert_alpha()
    life_rect = life_image.get_rect()
    life_num = 10

    # 游戏结束画面
    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()

    DOUBLE_BULLET_TIME = USEREVENT + 1

    # 解除我方飞机无敌状态
    INVINCEBLE_TIME = USEREVENT + 2

    # 生成超级子弹
    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)))

    # 标记是否使用超级子弹
    is_double_bullet = False

    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.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

    # 阻止重复读取成绩记录文件
    recorded = False

    # 标志是否暂停游戏
    paused = False
    paused_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 = paused_nor_image.get_rect()
    paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
    paused_image = paused_nor_image

    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()
                        paused_image = resume_pressed_image
                    else:
                        pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
                        pygame.mixer.music.unpause()
                        pygame.mixer.unpause()
                        paused_image = pause_pressed_image
            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 = paused_nor_image
            elif event.type == KEYDOWN:
                if event.key == K_ < em class ="Highlight" style="padding: 1px; box-shadow: rgb(229, 229, 229) 1px 1px; border-radius: 3px; -webkit-print-color-adjust: exact; background-color: rgb(255, 255, 102); color: rgb(0, 0, 0); font-style: inherit;" > SPA < / em > CE:
                    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]):
                    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)
Beispiel #5
0
def main():
    pygame.mixer.music.play(-1)
    score = 0
    level = 1
    score_font = pygame.font.Font("font/font.ttf", 36)
    #全屏炸弹
    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.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 10 * 1000)

    #超级子弹定时器
    DOUBLE_BULLET_TIME = USEREVENT + 1
    is_double_bullet = False
    #设置生命次数
    life_num = 3
    life_image = pygame.image.load("images/life.png")
    life_rect = life_image.get_rect()

    #标志是否暂停游戏
    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
    pause_image = pause_nor_image
    # 重新开始结束游戏
    again = pygame.image.load("images/again.png").convert_alpha()
    gameover = pygame.image.load("images/gameover.png").convert_alpha()
    again_rect = again.get_rect()
    gameover_rect = gameover.get_rect()
    #生成我方飞机
    me = myplant.Myplane(bg_size)
    #切换飞机图片
    transPlane = True
    #延迟变量
    delay = 100
    #生成敌机
    enemies = pygame.sprite.Group()
    #摧毁图片索引
    small_destroy = 0
    mid_destroy = 0
    big_destroy = 0
    my_destroy = 0

    small_enenmies = pygame.sprite.Group()
    add_small_enemies(small_enenmies, enemies, 15)

    mid_enenmies = pygame.sprite.Group()
    add_mid_enemies(mid_enenmies, enemies, 4)

    big_enenmies = pygame.sprite.Group()
    add_big_enemies(big_enenmies, enemies, 1)

    #生成普通子弹
    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)))
    clock = pygame.time.Clock()

    running = True

    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                # 重新开始 结束游戏
                if event.button == 1 and gameover_rect.collidepoint(event.pos):
                    pygame.quit()
                    sys.exit()
                if event.button == 1 and again_rect.collidepoint(event.pos):
                    main()

                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()
                    else:
                        pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
                        pygame.mixer.music.unpause()

            elif event.type == MOUSEMOTION:

                if paused_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
                        for each in enemies:
                            if each.rect.bottom > 0:
                                each.active = False

            elif event.type == SUPPLY_TIME:
                if randint(0, 2):
                    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)

        #根据用户得分增加难度
        if level == 1 and score > 50000:
            level = 2
            #增加3小2中1大
            add_small_enemies(small_enenmies, enemies, 3)
            add_mid_enemies(mid_enenmies, enemies, 2)
            add_big_enemies(big_enenmies, enemies, 1)
            #提升小型速度
            inc_speed(small_enenmies, 1)
        elif level == 2 and score > 200000:
            level = 3
            #增加3小2中1大
            add_small_enemies(small_enenmies, enemies, 5)
            add_mid_enemies(mid_enenmies, enemies, 3)
            add_big_enemies(big_enenmies, enemies, 2)
            #提升小型速度
            inc_speed(small_enenmies, 1)
            inc_speed(mid_enenmies, 1)
        elif level == 3 and score > 600000:
            level = 4
            #增加3小2中1大
            add_small_enemies(small_enenmies, enemies, 5)
            add_mid_enemies(mid_enenmies, enemies, 3)
            add_big_enemies(big_enenmies, enemies, 2)
            #提升小型速度
            inc_speed(small_enenmies, 1)
            inc_speed(mid_enenmies, 1)
        elif level == 4 and score > 1000000:
            level = 5
            #增加3小2中1大
            add_small_enemies(small_enenmies, enemies, 5)
            add_mid_enemies(mid_enenmies, enemies, 3)
            add_big_enemies(big_enenmies, enemies, 2)
            #提升小型速度
            inc_speed(small_enenmies, 1)
            inc_speed(mid_enenmies, 1)
        screen.blit(background, (0, 0))
        #游戏动态程序

        if paused or life_num == 0:
            pygame.time.set_timer(SUPPLY_TIME, 0)
            pygame.mixer.music.pause()
            screen.blit(again,
                        ((width - again_rect.width) // 2, height // 2 - 20))
            screen.blit(gameover,
                        ((width - gameover_rect.width) // 2, height // 2 + 20))
        else:
            # 检测键盘操作
            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):
                    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):
                    is_double_bullet = True
                    pygame.time.set_timer(DOUBLE_BULLET_TIME, 10 * 1000)
                    bullet_supply.active = False

            #绘制大型敌机
            for each in big_enenmies:
                if each.active:
                    each.move()
                    if transPlane and (delay % 5 == 0):
                        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)
                else:
                    #毁灭

                    if not (delay % 3):
                        screen.blit(each.destroy_images[big_destroy],
                                    each.rect)
                        big_destroy = (big_destroy + 1) % 6
                        if big_destroy == 0:
                            each.reset()
                            score += 10000

        #绘制中小型机
            for each in mid_enenmies:
                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)
                    # 当生命大于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):
                        screen.blit(each.destroy_images[mid_destroy],
                                    each.rect)
                        mid_destroy = (mid_destroy + 1) % 4
                        if mid_destroy == 0:
                            each.reset()
                            score += 6000

            for each in small_enenmies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                else:

                    if not (delay % 3):
                        screen.blit(each.destroy_images[small_destroy],
                                    each.rect)
                        small_destroy = (small_destroy + 1) % 4
                        if small_destroy == 0:
                            each.reset()
                            score += 1000

            #检测我方飞机是否被撞
            enemies_down = pygame.sprite.spritecollide(
                me, enemies, False, pygame.sprite.collide_mask)
            if enemies_down:
                me.active = False

                for e in enemies_down:
                    e.active = False
            #绘制我方飞机
            if me.active:
                transPlane = not transPlane
                if transPlane and (delay % 5 == 0):
                    screen.blit(me.image1, me.rect)
                else:
                    screen.blit(me.image2, me.rect)
            else:

                if not (delay % 3):
                    screen.blit(me.destroy_images[my_destroy], me.rect)
                    my_destroy = (my_destroy + 1) % 4
                    if my_destroy == 0:
                        life_num -= 1
                        me.reset()

            #绘制子弹
            if not (delay % 10):
                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 not in small_enenmies:
                                screen.blit(e.image_hit, e.rect)
                            e.energy -= 1
                            if e.energy == 0:
                                e.active = False

        delay -= 1
        if not delay:
            delay = 100
        screen.blit(pause_image, paused_rect)
        score_text = score_font.render("Score : %s" % str(score), True, BLACK)
        screen.blit(score_text, (10, 5))
        # 绘制炸弹数量
        bomb_text = bomb_font.render(" * %d" % bomb_num, True, RED)
        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))
        # 绘制生命次数

        life_text = score_font.render("* %d" % life_num, True, RED)
        life_text_rect = life_text.get_rect()
        screen.blit(life_image,
                    (width - life_text_rect.width - 30 - life_rect.width,
                     height - 5 - life_rect.height))
        screen.blit(life_text, (width - life_text_rect.width - 20,
                                height - 5 - life_text_rect.height))

        pygame.display.flip()

        clock.tick(60)
Beispiel #6
0
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, 5)
    # 大型飞机
    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(me.rect.midtop))

    # 中弹图片序列
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    me_destroy_index = 0

    switch_image = True
    delay = 100
    clock = pygame.time.Clock()
    running = True

    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        # 检测用户按键操作
        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()

        screen.blit(background, (0, 0))

        # 绘制子弹
        if not (delay % 10):
            bullet1[bullet1_index].reset(me.rect.midtop)
            bullet1_index = (bullet1_index + 1) % BULLET1_NUM
        # 检测子弹是否击中
        for b in bullet1:
            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 large_enemies:
                            e.hit = True
                            e.energy -= 1
                            if e.energy == 0:
                                e.active = False
                        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_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.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)

                # 出现时候的音效
                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()
                        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:
                        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:
                        each.reset()

        # 碰撞检测 ( pygame.sprite.collide_mask 表示将图片的透明部分删除后做碰撞检测 )
        enemies_down = pygame.sprite.spritecollide(me, enemies, False,
                                                   pygame.sprite.collide_mask)
        if enemies_down:
            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:
            # 毁灭
            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:
                    print()
                    running = False

        if not (delay % 5):
            switch_image = not switch_image

        delay -= 1

        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Beispiel #7
0
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))

    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)
    # 全屏炸弹
    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

    # 生成补给
    bomb_supply = supply.Bomb_Supply(bg_size)

    #用于切换图片
    switch_image = True
    #生命数量
    life_num = 1
    # 游戏结束画面
    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()

    #用于延迟
    delay = 100
    running = True

    while running:
        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
        screen.blit(background, (0, 0))
        #检测用户键盘操作
        key_pressed = pygame.key.get_pressed()
        if life_num:
            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()

        # 绘制全屏炸弹补给
        bomb_supply.move()
        screen.blit(bomb_supply.image, bomb_supply.rect)
        screen.blit(background, (0, 0))
        #发射子弹
        if not (delay % 10):
            bullet_sound.play()
            bullet1[bullet1_index].reset(me.rect.midtop)
            bullet1_index = (bullet1_index + 1) % BULLET1_NUM
        #检测子弹是否击中敌机
        for b in bullet1:
            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.energy -= 1
                            if e.energy == 0:
                                e.active = False
                        else:
                            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)
                #当生命值大于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()
                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()
        #检测飞机是否被碰撞
        enemy_down = pygame.sprite.spritecollide(me, enemies, False)
        if enemy_down:
            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_images[me_destroy_index], me.rect)
                me_destroy_index = (me_destroy_index + 1) % 4
                if me_destroy_index == 0:
                    life_num = 0
                    me.reset()

            # 绘制全屏炸弹数量
        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("Score : %s" % str(score), True, WHITE)
        screen.blit(score_text, (10, 5))
        # 绘制结束界面
        if life_num == 0:
            # 背景音乐停止
            pygame.mixer.music.stop()
            # 停止全部音效
            pygame.mixer.stop()

            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)

        #切换图片,60帧,一秒切换12次
        if not (delay % 5):
            switch_image = not switch_image

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Beispiel #8
0
def main():
    pygame.mixer.music.play(-1)  # -1代表音乐循环播放

    #生成我方飞机的实例化对象
    me = myplane.MyPlane(bg_size)  #引用别的文件的类,要把文件名打在类名前面
    #生成敌方飞机的实例化对象
    enemies = pygame.sprite.Group()  #建一个Group来装入所有类型的敌机,用于进行碰撞检测
    #生成小型飞机
    small_enemies = pygame.sprite.Group()  #建一个Group来装小型飞机,用于处理小型飞机的变化
    add_small_enemies(small_enemies, enemies, 15)  #调用方法,用来把飞机添加到Group中
    #生成中型飞机
    mid_enemies = pygame.sprite.Group()  #建一个Group来装小型飞机,用于处理小型飞机的变化
    add_mid_enemies(mid_enemies, enemies, 4)  #调用方法,用来把飞机添加到Group中
    #生成大型飞机
    big_enemies = pygame.sprite.Group()  #建一个Group来装小型飞机,用于处理小型飞机的变化
    add_big_enemies(big_enemies, enemies, 2)  #调用方法,用来把飞机添加到Group中

    #生成特殊飞机group
    special_enemies = pygame.sprite.Group()  #建一个Group来装特殊飞机,用于处理特殊飞机的变化
    #初始化特殊飞机数目为5
    special_enemies_num = 5

    #生成普通子弹
    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_level = 0
    bullet_font = pygame.font.Font("font/font.ttf", 20)

    #生成终极子弹
    bullet3 = []
    bullet3_index = 0
    BULLET3_NUM = 20
    for i in range(BULLET3_NUM // 5):
        bullet3.append(bullet.Bullet1((me.rect.centerx - 58, me.rect.centery)))
        bullet3.append(bullet.Bullet1((me.rect.centerx + 55, me.rect.centery)))
        bullet3.append(
            bullet.Bullet1((me.rect.centerx - 27, me.rect.centery - 21)))
        bullet3.append(
            bullet.Bullet1((me.rect.centerx + 24, me.rect.centery - 21)))
        bullet3.append(bullet.Bullet1(me.rect.midtop))

    #中弹图片索引
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    e4_destroy_index = 0
    me_destroy_index = 0

    #用于我方飞机切换图片的判断变量
    switch_image = True

    #用于延时的变量
    delay = 100

    #分数初始化
    score = 0
    #载入分数字体
    score_font = pygame.font.Font("font/font.ttf", 30)

    #游戏难度初始化
    level = 1

    #一开始小型机,中型机 不会斜向飞行
    small_direction_change = False
    mid_direction_change = False

    #炸弹初始化
    bomb_num = 3
    bomb_image = pygame.image.load("Images/shoot/bomb.png").convert_alpha()
    bomb_font = pygame.font.Font("font/font.ttf", 40)
    bomb_rect = bomb_image.get_rect()

    #游戏暂停按钮
    paused = False
    paused_nor_image = pygame.image.load(
        "Images/shoot/game_pause_nor.png").convert_alpha()
    paused_pressed_image = pygame.image.load(
        "Images/shoot/game_pause_pressed.png").convert_alpha()
    resume_nor_image = pygame.image.load(
        "Images/shoot/game_resume_nor.png").convert_alpha()
    resume_pressed_image = pygame.image.load(
        "Images/shoot/game_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  #pause按钮的默认初始状态

    #游戏道具的发放
    bullet_supply = supply.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    #设定道具发定时器(自定义事件)
    SUPPLY_TIME = USEREVENT  #定义一个自定义事件 名叫 SUPPLY_TIME
    pygame.time.set_timer(SUPPLY_TIME, 10 * 1000)  #每10秒产生一次自定义事件SUPPLY_TIME

    #超级子弹定时器(自定义事件)
    DOUBLE_BULLET_TIME_FINISH = USEREVENT + 1  #定义一个自定义事件 名叫 DOUBLE_BULLET_TIME_FINISH 用来限制超级子弹使用的事件
    #标志是否正在使用超级子弹
    is_double_bullet = False

    #解除我方飞机无敌状态定时器(自定义事件)
    INVINCIBLE_TIME_FINISH = USEREVENT + 2  #自定义事件:用于暂停飞机无敌

    #突发特殊小飞机定时器(自定义事件)
    SPECIAL_TIME = USEREVENT + 3
    pygame.time.set_timer(SPECIAL_TIME, randint(20, 60) * 1000)  #每20-60秒触发一次

    #我方飞机生命数量
    life_image = pygame.image.load("Images/shoot/life.png").convert_alpha()
    life_image_rect = life_image.get_rect()
    life_num_font = pygame.font.Font("font/font.ttf", 40)
    life_num = 3

    #用于阻止重复打开记录文件
    recorded = False

    #游戏结束画面,字体
    record_score_font = pygame.font.Font("font/font.ttf", 35)
    finial_score_font = pygame.font.Font("font/font.ttf", 40)
    gameover_font = pygame.font.Font("font/font.ttf", 25)
    again_image = pygame.image.load(
        "Images/shoot/kuangkuang.png").convert_alpha()
    again_image_rect = again_image.get_rect()
    close_image = pygame.image.load(
        "Images/shoot/kuangkuang.png").convert_alpha()
    close_image_rect = close_image.get_rect()

    #用于延时主循环,控制游戏帧数,保护cpu
    clock = pygame.time.Clock()

    #游戏主循环
    running = True
    while running:
        for event in pygame.event.get():  #检测事件循环
            #触发退出事件
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            #触发鼠标移动事件
            elif event.type == MOUSEBUTTONDOWN:
                if event.button == 1 and paused_rect.collidepoint(
                        event.pos):  #第二个条件的意思:当鼠标移动到paused_rect位置时返回True
                    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):  #判断鼠标的位置是否在paused_rect这个位置上,如果是就显示“深 色”图标
                    if paused:
                        paused_image = resume_pressed_image  #如果在暂停的情况下,图片变成“深 色 继 续”图片
                    else:
                        paused_image = paused_pressed_image  #如果在继续的情况下,图片变成“深 色 暂 停”图片
                else:  #如果鼠标没在paused_rect上方的话,就显示 “浅 色” 图标
                    if paused:
                        paused_image = resume_nor_image
                    else:
                        paused_image = paused_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]):  #在True 和 False 中 随机选一个
                    bomb_supply.reset()
                else:
                    bullet_supply.reset()

            #触发超级子弹结束
            elif event.type == DOUBLE_BULLET_TIME_FINISH:
                is_double_bullet = False  #超级子弹效果取消
                pygame.time.set_timer(DOUBLE_BULLET_TIME_FINISH,
                                      0)  #暂停自定义事件的产生

            #触发解除飞机无敌事件
            elif event.type == INVINCIBLE_TIME_FINISH:
                me.invincible = False
                pygame.time.set_timer(INVINCIBLE_TIME_FINISH, 0)

            #触发特殊飞机事件
            elif event.type == SPECIAL_TIME:
                enemy.SpecialEnemy.happen = True
                #生成特殊飞机
                add_special_enemies(special_enemies, enemies,
                                    special_enemies_num)  #调用方法,用来把飞机添加到Group中

        #游戏难度
        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 > 100000:
            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)
            #小型飞机开始斜向飞行
            small_direction_change = True
            #特殊小飞机数目+1
            special_enemies_num += 1
        elif level == 3 and score > 200000:
            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)
            life_num += 1
            #特殊小飞机数目+2
            special_enemies_num += 2
        elif level == 4 and score > 450000:
            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)
            #中型机飞行方向改变
            mid_direction_change = True
            life_num += 1
            #特殊小飞机数目+2
            special_enemies_num += 2
        elif level == 4 and score > 800000:
            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)
            life_num += 1
            #特殊小飞机数目+2
            special_enemies_num += 2
        elif level == 5 and score > 1000000:
            level = 6
            upgrade_sound.play()
            inc_speed(small_enemies, 1)
            enemy.MidEnemy.energy = 13
            enemy.BigEnemy.energy = 25
        elif level == 6 and score > 1500000:
            level = 7
            upgrade_sound.play()
            inc_speed(small_enemies, 2)
            inc_speed(mid_enemies, 1)
            enemy.MidEnemy.energy = 18
            enemy.BigEnemy.energy = 35
        elif level == 7 and score > 2000000:
            level = 8
            upgrade_sound.play()
            inc_speed(small_enemies, 2)
            inc_speed(mid_enemies, 2)
            inc_speed(big_enemies, 1)
            enemy.MidEnemy.energy = 20
            enemy.BigEnemy.energy = 40

        #绘制背景图
        screen.blit(background, (0, 0))

        #当生命数大于0,还有没按下暂停时,游戏才继续进行
        if life_num and not paused:
            #检测用户的键盘操作
            key_press = pygame.key.get_pressed(
            )  #获取键盘上所有键的状态,返回一个bool值序列,表示键是否被按下
            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):  #直接检测bomb_supply, me两个精灵是否发生碰撞
                    get_bomb_sound.play()
                    if bomb_num < 5:  #如果原本炸弹数<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):  #直接检测bomb_supply, me两个精灵是否发生碰撞
                    get_bullet_sound.play()
                    bullet_supply.active = False
                    bullet2_level += 1  #超级子弹等级+1
                    #如果超级子弹等级小于8,则发射超级子弹
                    if bullet2_level < 8:
                        is_double_bullet = True  #开始发射超级子弹
                        pygame.time.set_timer(
                            DOUBLE_BULLET_TIME_FINISH, 18 * 1000
                        )  #自定义事件DOUBLE_BULLET_TIME_FINISH将在18秒后产生(18秒后,超级子弹失效)
                        #生成超级子弹
                        if bullet2_level == 1:  # 1级:每次发2颗
                            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)))
                        elif bullet2_level == 2:  # 2级:每次发3颗
                            BULLET2_NUM = 12
                            for i in range(BULLET2_NUM // 3):
                                bullet2.append(
                                    bullet.Bullet2((me.rect.centerx - 33,
                                                    me.rect.centery)))
                                bullet2.append(
                                    bullet.Bullet2((me.rect.centerx + 30,
                                                    me.rect.centery)))
                                bullet2.append(bullet.Bullet2(me.rect.midtop))
                        elif bullet2_level == 3:  # 3级:每次发4颗
                            BULLET2_NUM = 16
                            for i in range(BULLET2_NUM // 4):
                                bullet2.append(
                                    bullet.Bullet2((me.rect.centerx - 43,
                                                    me.rect.centery)))
                                bullet2.append(
                                    bullet.Bullet2((me.rect.centerx + 40,
                                                    me.rect.centery)))
                                bullet2.append(
                                    bullet.Bullet2((me.rect.centerx - 18,
                                                    me.rect.centery)))
                                bullet2.append(
                                    bullet.Bullet2((me.rect.centerx + 15,
                                                    me.rect.centery)))
                        elif 4 <= bullet2_level < 8:  # 4级~7级:每次发5颗
                            BULLET2_NUM = 20
                            for i in range(BULLET2_NUM // 5):
                                bullet2.append(
                                    bullet.Bullet2((me.rect.centerx - 58,
                                                    me.rect.centery)))
                                bullet2.append(
                                    bullet.Bullet2((me.rect.centerx + 55,
                                                    me.rect.centery)))
                                bullet2.append(
                                    bullet.Bullet2((me.rect.centerx - 27,
                                                    me.rect.centery - 21)))
                                bullet2.append(
                                    bullet.Bullet2((me.rect.centerx + 24,
                                                    me.rect.centery - 21)))
                                bullet2.append(bullet.Bullet2(me.rect.midtop))
                    #如果超级子弹等级已经到达8级,就不触发超级子弹了,而是触发终极子弹
                    if bullet2_level == 8:
                        is_double_bullet = 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):  #每次当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  #这里是一个小技巧,这样 e3_destroy_index的值只能是0~5
                        if e3_destroy_index == 0:  #当飞机毁灭图片显示完时,就重置飞机
                            enemy3_fly_sound.stop()
                            score += 10000
                            each.reset()

            #绘制中型飞机
            for each in mid_enemies:
                if each.active:
                    #飞机移动
                    if not mid_direction_change:
                        each.direction -= each.direction  #这样写能确保在direction_change激活前,保持中型机都垂直飞行的
                    each.move()
                    if each.rect.right >= width:
                        each.direction = -each.direction
                    elif each.rect.left <= 0:
                        each.direction = -each.direction
                    screen.blit(each.image, each.rect)
                    #绘制飞机
                    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):  #每次当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  #这里是一个小技巧,这样 e2_destroy_index的值只能是0~3
                        if e2_destroy_index == 0:  #当飞机毁灭图片显示完时,就重置飞机
                            score += 6000
                            each.reset()

            #绘制小型飞机
            for each in small_enemies:
                if each.active:
                    if not small_direction_change:
                        each.direction -= each.direction  #这样写能确保在direction_change激活前,保持小型机都垂直飞行的
                    each.move()
                    if each.rect.right >= width:
                        each.direction = -each.direction
                    elif each.rect.left <= 0:
                        each.direction = -each.direction
                    screen.blit(each.image, each.rect)
                else:
                    #飞机毁灭
                    if not (delay % 3):  #每次当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  #这里是一个小技巧,这样 e1_destroy_index的值只能是0~3
                        if e1_destroy_index == 0:  #当飞机毁灭图片显示完时,就重置飞机
                            score += 1000
                            each.reset()

            if special_enemies:
                #绘制特殊飞机
                for each in special_enemies:
                    if each.active and not each.death:  #要还在活动的和之前还没死过的小飞机才能move
                        each.move()
                        screen.blit(each.image, each.rect)
                    else:
                        #飞机毁灭
                        if not (delay % 3):  #每次当delay能整除3的时候,就显示一张图片
                            if e4_destroy_index == 0:
                                enemy1_down_sound.play()
                            screen.blit(each.destroy_images[e4_destroy_index],
                                        each.rect)
                            e4_destroy_index = (
                                e4_destroy_index +
                                1) % 1  #这里是一个小技巧,这样 e1_destroy_index的值只能是0~3
                            if e4_destroy_index == 0:  #当飞机毁灭图片显示完时,就把小飞机移除出group
                                each.reset(
                                )  #重置飞机位置,并且active = True, death = True
                                special_enemies.remove(each)  #把死了的飞机移除出group
                                score += 1000

            #绘制子弹
            #子弹延时显示设置
            if not (delay % 10):  #每10帧重置一次图片
                bullet_sound.play()
                if is_double_bullet and bullet2_level > 0:  #如果是超级子弹
                    if bullet2_level == 1:
                        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  #索引+1
                    elif bullet2_level == 2:
                        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))
                        bullets[bullet2_index + 2].reset(me.rect.midtop)
                        bullet2_index = (bullet2_index +
                                         3) % BULLET2_NUM  #索引+1
                    elif bullet2_level == 3:
                        bullets = bullet2
                        bullets[bullet2_index].reset(
                            (me.rect.centerx - 43, me.rect.centery))
                        bullets[bullet2_index + 1].reset(
                            (me.rect.centerx + 40, me.rect.centery))
                        bullets[bullet2_index + 2].reset(
                            (me.rect.centerx - 18, me.rect.centery))
                        bullets[bullet2_index + 3].reset(
                            (me.rect.centerx + 15, me.rect.centery))
                        bullet2_index = (bullet2_index +
                                         4) % BULLET2_NUM  #索引+1
                    elif 4 <= bullet2_level < 8:
                        bullets = bullet2
                        bullets[bullet2_index].reset(
                            (me.rect.centerx - 58, me.rect.centery))
                        bullets[bullet2_index + 1].reset(
                            (me.rect.centerx + 55, me.rect.centery))
                        bullets[bullet2_index + 2].reset(
                            (me.rect.centerx - 27, me.rect.centery - 21))
                        bullets[bullet2_index + 3].reset(
                            (me.rect.centerx + 24, me.rect.centery - 21))
                        bullets[bullet2_index + 4].reset(me.rect.midtop)
                        bullet2_index = (bullet2_index +
                                         5) % BULLET2_NUM  #索引+1

                elif bullet2_level >= 8:
                    bullets = bullet3
                    bullets[bullet3_index].reset(
                        (me.rect.centerx - 58, me.rect.centery))
                    bullets[bullet3_index + 1].reset(
                        (me.rect.centerx + 55, me.rect.centery))
                    bullets[bullet3_index + 2].reset(
                        (me.rect.centerx - 27, me.rect.centery - 21))
                    bullets[bullet3_index + 3].reset(
                        (me.rect.centerx + 24, me.rect.centery - 21))
                    bullets[bullet3_index + 4].reset(me.rect.midtop)
                    bullet3_index = (bullet3_index + 5) % BULLET3_NUM  #索引+1

                else:  #如果是普通子弹
                    bullets = bullet1
                    bullets[bullet1_index].reset(me.rect.midtop)
                    bullet1_index = (bullet1_index + 1) % BULLET1_NUM  #索引+1
            #显示子弹
            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

            #绘制我方飞机
            if me.active:
                if switch_image:
                    screen.blit(me.image1, me.rect)
                else:
                    screen.blit(me.image2, me.rect)
            else:
                #飞机毁灭
                if not (delay % 3):  #每次当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  #这里是一个小技巧,这样 me_destroy_index的值只能是0~3
                    if me_destroy_index == 0:  #当飞机毁灭图片显示完时,就重置飞机
                        life_num -= 1
                        me.reset()
                        if 0 < bullet2_level < 8:  #如果在8级以下,0级以上,则级数-1
                            bullet2_level -= 1
                        elif bullet2_level >= 8:  #如果当前超级子弹等级为8级或以上,则级数-2
                            bullet2_level -= 2
                        pygame.time.set_timer(INVINCIBLE_TIME_FINISH,
                                              3 * 1000)  #调用自定义事件,3秒后结束飞机无敌

            #检测我方飞机是否发生碰撞
            enemies_down = pygame.sprite.spritecollide(
                me, enemies, False, pygame.sprite.collide_mask
            )  #判断me是否与enemies中的任何一个发生碰撞,返回一个列表,里面装了与me发生碰撞的enemies
            if enemies_down and not me.invincible:  #当有敌机坠毁,而且我方飞机不是无敌的时候
                me.active = False  #我方飞机坠毁
                for each in enemies_down:
                    each.active = False  #敌方飞机坠毁

            #绘制全屏炸弹图片
            bomb_text = bomb_font.render("x %d" % bomb_num, True,
                                         BLACK)  #把text转化成surface
            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))  #显示数字

            #绘制剩余生命数量
            life_text = life_num_font.render(str(life_num), True,
                                             BLACK)  #把text转化为surface
            life_text_rect = life_text.get_rect()
            screen.blit(life_image,
                        (width - life_image_rect.width - life_text_rect.width,
                         height - 10 - life_image_rect.height))  #显示图片
            screen.blit(life_text,
                        (width - life_text_rect.width,
                         height - 10 - life_text_rect.height))  #显示数字

            #绘制超级子弹等级
            bullet_text = bullet_font.render("Lv:" + str(bullet2_level), True,
                                             BLACK)
            screen.blit(bullet_text, (10, 40))

            #绘制分数
            score_text = score_font.render("Score : %s" % str(score), True,
                                           BLACK)
            screen.blit(score_text, (10, 5))

        #否则,当生命数<0时,就绘制结束画面
        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:
                    record_score = score
                    with open("record.txt", "w") as f:
                        f.write(str(score))

            ############################################绘制结束画面######################################################

            #绘制字体“Best:”
            record_score_text = record_score_font.render(
                "Best : %d" % record_score, True, BLACK)
            screen.blit(record_score_text, (50, 50))

            #绘制字体“Your Score”
            gameover_text1 = finial_score_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 - 500
            screen.blit(gameover_text1, gameover_text1_rect)

            #绘制最终分数
            gameover_text2 = finial_score_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, height - 450
            screen.blit(gameover_text2, gameover_text2_rect)

            #绘制两个框框
            again_image_rect.left, again_image_rect.top = (
                width - again_image_rect.width) // 2, height - 390
            screen.blit(again_image, again_image_rect)
            close_image_rect.left, close_image_rect.top = (
                width - close_image_rect.width) // 2, height - 320
            screen.blit(close_image, close_image_rect)

            #绘制框框里的字
            again_text = gameover_font.render("Try Again", True, BLACK)
            again_text_rect = again_text.get_rect()
            again_text_rect.left, again_text_rect.top = (
                width - again_text_rect.width) // 2, height - 385
            screen.blit(again_text, again_text_rect)
            close_text = gameover_font.render("End", True, BLACK)
            close_text_rect = close_text.get_rect()
            close_text_rect.left, close_text_rect.top = (
                width - close_text_rect.width) // 2, height - 315
            screen.blit(close_text, close_text_rect)

            #框框按钮触发
            if pygame.mouse.get_pressed()[0]:  #如果用户按下鼠标左键
                pos = pygame.mouse.get_pos()  #获取鼠标坐标
                if again_image_rect.left < pos[0] < again_image_rect.right and \
                   again_image_rect.top < pos[1] < again_image_rect.bottom: #如果按了“Try Again”
                    main()  # 调用main函数,重新开始游戏

                elif close_image_rect.left < pos[0] < close_image_rect.right and \
                     close_image_rect.top < pos[1] < close_image_rect.bottom: #如果按了“End”
                    pygame.quit()  #退出游戏
                    sys.exit()

        #图片延时操作
        if not (delay % 5):  #每次当delay能整除5时,就变换图片
            switch_image = not switch_image
        delay -= 1
        if not delay:
            delay = 100

        #绘制暂停按钮
        screen.blit(paused_image, paused_rect)

        pygame.display.flip()

        clock.tick(60)
Beispiel #9
0
def main():
    pygame.mixer.music.play(-1)

    #生成我方飞机
    me = myplane.Myplane(bg_size)

    enemies = pygame.sprite.Group()

    #生成敌方小型飞机
    S_enemies = pygame.sprite.Group()
    add_S_enemies(S_enemies, enemies, 15)
    #生成敌方中型飞机
    M_enemies = pygame.sprite.Group()
    add_M_enemies(M_enemies, enemies, 5)
    #生成敌方大型飞机
    X_enemies = pygame.sprite.Group()
    add_X_enemies(X_enemies, enemies, 2)

    #生成普通子弹
    bullet1 = []
    bullet1_index = 0
    BULLET_NUM = 5
    for i in range(BULLET_NUM):
        bullet1.append(bullet.Bullet1(me.rect.midtop))
    #生成超级子弹
    bullet2 = []
    double_bullet = False
    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)))

    clock = pygame.time.Clock()

    #毁灭图片索引
    e1_destory_index = 0
    e2_destory_index = 0
    e3_destory_index = 0
    me_destory_index = 0

    #统计得分
    score = 0

    #设置游戏难度
    level = 1

    #设置全屏炸弹
    bomb_image = pygame.image.load("images/bomb.png").convert_alpha()
    bomb_rect = bomb_image.get_rect()
    bomb_num = 3
    bomb_rect.left, bomb_rect.bottom = 0, height

    #每10秒发放一个补给包
    bullet_supply = supply.Bullet_supply(bg_size)
    bomb_supply = supply.Bomb_supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 15 * 1000)

    #用于解除超级子弹状态定时器
    DOUBLE_BULLET_TIME = USEREVENT + 1

    #用于切换我方飞机图片
    switch_image = True

    #用于绘制暂停按钮
    paused = False
    pause_image1 = pygame.image.load("images/pause1.png").convert_alpha()
    pause_image = pygame.image.load("images/pause2.png").convert_alpha()
    pause_rect = pause_image.get_rect()
    pause_rect.right, pause_rect.top = width, 0

    #生命数量
    life_num = 3
    life_image = pygame.image.load("images/life_image.png").convert_alpha()
    life_rect = life_image.get_rect()
    life_rect.right, life_rect.bottom = width, height

    #用于绘制结束画面
    game_over_image1 = pygame.image.load(
        "images/game_over2.png").convert_alpha()
    game_over_image2 = pygame.image.load(
        "images/game_over1.png").convert_alpha()
    game_over_image_rect = game_over_image1.get_rect()
    game_over_image_rect.centerx, game_over_image_rect.centery = width / 2, height / 2

    #用于阻止重复打开recored
    recoreded = False

    #用于延迟
    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 pause_rect.collidepoint(event.pos):
                    paused = not paused
                    pause_image, pause_image1 = pause_image1, pause_image

                elif event.button == 1 and game_over_image_rect.collidepoint(
                        event.pos) and life_num == 0:
                    main()

            elif event.type == SUPPLY_TIME:
                if not paused:
                    supply_sound.play()
                    if choice([True, False]):
                        bomb_supply.reset()
                    else:
                        bullet_supply.reset()

            elif event.type == DOUBLE_BULLET_TIME:
                double_bullet = False
                pygame.time.set_timer(DOUBLE_BULLET_TIME, 0)

            elif event.type == KEYDOWN:
                if event.key == K_SPACE:
                    if bomb_num:
                        bomb_num -= 1
                        use_bomb_sound.play()
                        for each in enemies:
                            if each.rect.bottom > 0:
                                each.active = False

        screen.blit(background1.image, background1.rect)
        screen.blit(background2.image, background2.rect)
        screen.blit(cloud1.image_s, cloud1.image_rect)
        screen.blit(cloud2.image_s, cloud2.image_rect)

        #绘制界面UI
        if life_num:
            #绘制暂停按钮
            screen.blit(pause_image, pause_rect)

            #绘制全屏炸弹示意图
            for i in range(bomb_num):
                bomb_rect.left = bomb_rect.left + i * bomb_rect.width
                screen.blit(bomb_image, bomb_rect)
                bomb_rect.left = 0
            #绘制剩余生命示意图
            for i in range(life_num):
                life_rect.right = life_rect.right - i * life_rect.width
                screen.blit(life_image, life_rect)
                life_rect.right = width
            #绘制结束画面
        else:
            #停止播放背景音乐
            pygame.mixer.music.stop()
            #停止播放全部营销
            pygame.mixer.stop()
            #停止发放补给
            pygame.time.set_timer(SUPPLY_TIME, 0)
            screen.blit(game_over_image1, game_over_image_rect)
            screen.blit(
                game_over_image2,
                (game_over_image_rect.left, game_over_image_rect.top + 64))

            #读取历史最高得分
            if not recoreded:
                recoreded = 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))

        #根据用户的得分增加难度
        if level == 1 and score == 5000:
            level = 2
            upgrade_sound.play()
            #增加 3架小型敌机、两两架中型敌机和一架大型敌机
            add_S_enemies(S_enemies, enemies, 5)
            add_M_enemies(M_enemies, enemies, 3)
            add_X_enemies(X_enemies, enemies, 1)
            #提升小型敌机的速度
            inc_speed(S_enemies, 1)
        elif level == 2 and score > 30000:
            level = 3
            upgrade_sound.play()
            #增加3架小型敌机、两两架中型敌机和一架大型敌机
            add_S_enemies(S_enemies, enemies, 5)
            add_M_enemies(M_enemies, enemies, 3)
            add_X_enemies(X_enemies, enemies, 1)
            #提升小型敌机的速度
            inc_speed(S_enemies, 2)
            inc_speed(M_enemies, 3)
        elif level == 3 and score > 100000:
            level = 4
            upgrade_sound.play()
            #增加3架小型敌机、两两架中型敌机和一架大型敌机
            add_S_enemies(S_enemies, enemies, 10)
            add_M_enemies(M_enemies, enemies, 5)
            add_X_enemies(X_enemies, enemies, 3)
            #提升小型敌机的速度
            inc_speed(S_enemies, 1)
            inc_speed(M_enemies, 1)

        if not paused and life_num:

            #背景移动
            background1.move()
            background2.move()
            cloud1.move()
            cloud2.move()

            #检测键盘输入
            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 key_pressed[K_LCTRL] or key_pressed[K_RCTRL]:
                me.invincible = True
            else:
                me.invincible = False

            #绘制全屏炸弹补给并检测是否获得
            if bomb_supply.active:
                bomb_supply.move()
                screen.blit(bomb_supply.image, bomb_supply.rect)
                if pygame.sprite.collide_mask(bomb_supply, me):
                    get_supply_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_supply_sound.play()
                    double_bullet = True
                    bullet_supply.active = False
                    pygame.time.set_timer(DOUBLE_BULLET_TIME, 5 * 1000)

            #发射子弹
            if not (delay % 10):
                if double_bullet:
                    bullets = bullet2
                    bullets[bullet2_index].reset(
                        (me.rect.centerx - 20, me.rect.centery))
                    bullets[bullet2_index + 1].reset(
                        (me.rect.centerx + 20, 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) % BULLET_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 M_enemies or e in X_enemies:
                                e.HP -= 1
                                e.hit = True
                                if e.HP == 0:
                                    e.active = False
                            else:
                                e.active = False

            #绘制大型敌机
            for each in X_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                    each.fly_image_rect.center = each.rect.center
                    screen.blit(each.fly_images[4], each.fly_image_rect)
                    if not (delay % 2):
                        screen.blit(each.fly_images[e3_destory_index],
                                    each.fly_image_rect)
                        e3_destory_index = (e3_destory_index + 1) % 4

                    #绘制大型敌机HP
                    pygame.draw.line(screen,black,\
                                    (each.rect.left,each.rect.top-5),\
                                    (each.rect.right,each.rect.top-5),2)
                    #当生命大于百分之20显示绿色,否则显示红色
                    HP_remain = each.HP / enemy.X_enemy.HP
                    if HP_remain > 0.2:
                        HP_color = green
                    else:
                        HP_color = red
                    pygame.draw.line(screen,HP_color,\
                                    (each.rect.left,each.rect.top-5),\
                                    (each.rect.left+each.rect.width*HP_remain,\
                                    each.rect.top-5),2)

                    if each.rect.bottom == -50:
                        X_enemy_out.play(-1)
                else:
                    #毁灭
                    if not (delay % 3):
                        screen.blit(each.destroy_images[e3_destory_index],
                                    each.rect)
                        e3_destory_index = (e3_destory_index + 1) % 4
                        if e3_destory_index == 0:
                            X_enemy_out.stop()
                            X_enemy_down.play()
                            score += 10000
                            each.reset()

            #绘制中型敌机
            for each in M_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)
                    #绘制大型敌机HP
                    pygame.draw.line(screen,black,\
                                    (each.rect.left,each.rect.top-5),\
                                    (each.rect.right,each.rect.top-5),2)
                    #当生命大于百分之20显示绿色,否则显示红色
                    HP_remain = each.HP / enemy.M_enemy.HP
                    if HP_remain > 0.2:
                        HP_color = green
                    else:
                        HP_color = red
                    pygame.draw.line(screen,HP_color,\
                                    (each.rect.left,each.rect.top-5),\
                                    (each.rect.left+each.rect.width*HP_remain,\
                                    each.rect.top-5),2)

                else:
                    #毁灭
                    if not (delay % 3):
                        screen.blit(each.destroy_images[e3_destory_index],
                                    each.rect)
                        e2_destory_index = (e2_destory_index + 1) % 4
                        if e2_destory_index == 0:
                            S_enemy_down.play()
                            score += 3000
                            each.reset()

            #绘制小型敌机
            for each in S_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                else:
                    #毁灭
                    if not (delay % 6):
                        screen.blit(each.destroy_images[e3_destory_index],
                                    each.rect)
                        e1_destory_index = (e1_destory_index + 1) % 4
                        S_enemy_down.play()
                        if e1_destory_index == 0:
                            score += 1000
                            each.reset()

            #j检测我方飞机是否被撞
            if me.invincible:
                me.mask = me.masks[1]
            else:
                me.mask = me.masks[0]
            enemies_down = pygame.sprite.spritecollide(
                me, enemies, False, pygame.sprite.collide_mask)
            if enemies_down:
                if not me.invincible:
                    me.active = False
                for e in enemies_down:
                    e.active = False

            #绘制我方飞机动画
            if me.active:
                if me.invincible:
                    me.invincible_image_rect.center = me.rect.center
                    screen.blit(me.invincible_image, me.invincible_image_rect)
                if switch_image:
                    screen.blit(me.image1, me.rect)
                else:
                    screen.blit(me.image2, me.rect)
            else:
                #我方毁灭
                if not (delay % 3):
                    screen.blit(each.destroy_images[me_destory_index],
                                each.rect)
                    me_destory_index = (me_destory_index + 1) % 4
                    if me_destory_index == 0:
                        me_down.play()
                        if life_num:
                            life_num -= 1
                            me.reset()
            screen.blit(cloud1.image_s, cloud1.image_rect)
            screen.blit(cloud2.image_s, cloud2.image_rect)

            #切换图片
            if not (delay % 5):
                switch_image = not switch_image
            delay -= 1
            if not delay:
                delay = 100
                print("战争文本 Score:%d 炸弹数量:%d 剩余数量%d" %
                      (score, bomb_num, life_num))

        pygame.display.flip()

        clock.tick(60)
Beispiel #10
0
def main():
    pygame.mixer.music.play(-1)

    #initialize gamer's plane
    me = myplane.MyPlane(bg_size)

    #initialize enemy planes
    enemies = pygame.sprite.Group()

    #initialize small enemies
    small_enemies = pygame.sprite.Group()
    add_small_enemies(small_enemies, enemies, 15)

    #initialize mid enemies
    mid_enemies = pygame.sprite.Group()
    add_mid_enemies(mid_enemies, enemies, 4)

    #initialize large enemies
    large_enemies = pygame.sprite.Group()
    add_large_enemies(large_enemies, enemies, 2)

    clock = pygame.time.Clock()

    #generate normal bullet
    bullet1 = []
    bullet1_index = 0
    BULLET1_NUM = 5
    for i in range(BULLET1_NUM):
        bullet1.append(bullet.Bullet1(me.rect.midtop))

    #generate super bullet
    bullet_speed = 10
    bullet2 = []
    bullet2_index = 0
    BULLET2_NUM = 16
    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)))

    # gamer's score
    score = 0
    score_font = pygame.font.Font("font/font.ttf", 36)

    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    me_destroy_index = 0

    # pasue and resume
    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

    # level
    level = 1

    # 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

    # supply every 30 seconds
    bullet_supply = supply.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

    # super bullet timer
    DOUBLE_BULLET_TIME = USEREVENT + 1
    is_double_bullet = False

    # hack mode timer
    HACKER_TIME = USEREVENT + 2

    # life remain
    life_image = pygame.image.load("images/life.png").convert_alpha()
    life_rect = life_image.get_rect()
    life_num = 3

    #for plane image switch
    switch_image = True

    # prevent repeating open files
    recorded = False

    # gameover images
    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()

    #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 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:
                        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]):
                    bullet_supply.reset()
                else:
                    bomb_supply.reset()

            elif event.type == DOUBLE_BULLET_TIME:
                is_double_bullet = False
                pygame.time.set_timer(DOUBLE_BULLET_TIME, 0)

            elif event.type == HACKER_TIME:
                me.hack_mode = False
                pygame.time.set_timer(HACKER_TIME, 0)

        # increase difficulty
        if level == 1 and score > 100000:
            level = 2
            upgrade_sound.play()
            # +3 small enemies, +2 mid enemies, +1 large enemy
            add_small_enemies(small_enemies, enemies, 3)
            add_mid_enemies(mid_enemies, enemies, 2)
            add_large_enemies(large_enemies, enemies, 1)
            # increase small enemies's speed
            increase_speed(small_enemies, 1)
        elif level == 2 and score > 200000:
            level = 3
            upgrade_sound.play()
            # +5 small enemies, +3 mid enemies, +1 large enemy
            add_small_enemies(small_enemies, enemies, 5)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_large_enemies(large_enemies, enemies, 1)
            # increase small and mid enemies's speed
            increase_speed(small_enemies, 1)
            increase_speed(mid_enemies, 1)
        elif level == 3 and score > 300000:
            level = 4
            upgrade_sound.play()
            # +5 small enemies, +3 mid enemies, +1 large enemy
            add_small_enemies(small_enemies, enemies, 5)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_large_enemies(large_enemies, enemies, 2)
            # increase small and mid enemies's speed
            increase_speed(small_enemies, 1)
            increase_speed(mid_enemies, 1)
        elif level == 4 and score > 500000:
            level = 5
            upgrade_sound.play()
            # +5 small enemies, +3 mid enemies, +1 large enemy
            add_small_enemies(small_enemies, enemies, 5)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_large_enemies(large_enemies, enemies, 2)
            # increase small and mid enemies's speed
            increase_speed(small_enemies, 1)
            increase_speed(mid_enemies, 1)

        screen.blit(background, (0, 0))

        if life_num and not paused:
            #key press
            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()

            # collision with supply
            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()
                    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

            # shoot bullet
            if not (delay % bullet_speed):
                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
                    bullet_speed = 5
                else:
                    bullets = bullet1
                    bullet1[bullet1_index].reset(me.rect.midtop)
                    bullet1_index = (bullet1_index + 1) % BULLET1_NUM
                    bullet_speed = 10

            #decet bullet collision
            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.pygame.sprite.collide_mask)
                    if enemy_hit:
                        b.active = False
                        for e in enemy_hit:
                            if e in mid_enemies or e in large_enemies:
                                e.hit = True
                                e.hp -= 1
                                if e.hp == 0:
                                    e.active = False
                            else:
                                e.active = False

            # large enemies on screen
            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)

                    # hp bar
                    pygame.draw.line(screen, WHITE,
                                     (each.rect.left, each.rect.top - 5),
                                     (each.rect.right, each.rect.top - 5), 2)
                    # display green if hp > 20%, else display red
                    hp_remain = each.hp / enemy.LargeEnemy.hp
                    if hp_remain > 0.2:
                        hp_color = GREEN
                    else:
                        hp_color = RED
                    pygame.draw.line(
                        screen, hp_color, (each.rect.left, each.rect.top - 5),
                        (each.rect.left + each.rect.width * hp_remain,
                         each.rect.top - 5), 2)

                    # generate sound effect for large enemies
                    if each.rect.bottom == -50:
                        enemy3_fly_sound.play(-1)
                else:
                    #destroy
                    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 on screen
            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)

                    # hp bar
                    pygame.draw.line(screen, WHITE,
                                     (each.rect.left, each.rect.top - 5),
                                     (each.rect.right, each.rect.top - 5), 2)
                    # display green if hp > 20%, else display red
                    hp_remain = each.hp / enemy.MidEnemy.hp
                    if hp_remain > 0.2:
                        hp_color = GREEN
                    else:
                        hp_color = RED
                    pygame.draw.line(
                        screen, hp_color, (each.rect.left, each.rect.top - 5),
                        (each.rect.left + each.rect.width * hp_remain,
                         each.rect.top - 5), 2)

                else:
                    #destroy
                    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 on screen
            for each in small_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                else:
                    #destroy
                    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()

            # showing gamer's plane on screen
            if me.active:
                if switch_image:
                    screen.blit(me.image1, me.rect)
                else:
                    screen.blit(me.image2, me.rect)
            else:
                #destroy
                if not (delay % 3):
                    if me_destroy_index == 0:
                        me_down_sound.play()
                    screen.blit(me.destroy_images[me_destroy_index], each.rect)
                    me_destroy_index = (me_destroy_index + 1) % 4
                    if me_destroy_index == 0:
                        life_num -= 1
                        me.reset()
                        # set hack time
                        pygame.time.set_timer(HACKER_TIME, 3 * 1000)

            # bomb number icon on screen
            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))

            # life remain icon on screen
            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 on screen
            score_text = score_font.render("Score : %s" % str(score), True,
                                           WHITE)
            screen.blit(score_text, (10, 5))

            #pause icon on screen
            screen.blit(paused_image, pause_rect)

            #detect gamer's plane collision
            enemies_down = pygame.sprite.spritecollide(
                me, enemies, False, pygame.sprite.collide_mask)
            if enemies_down and not me.hack_mode:
                me.active = False  #!!!!!!!!!!!!!!!!!!!!!
                for e in enemies_down:
                    e.active = False

        # game over screen
        elif life_num == 0:
            # stop bg music
            pygame.mixer.music.stop()

            # stop mixers
            pygame.mixer.stop()

            # stop supply
            pygame.time.set_timer(SUPPLY_TIME, 0)

            if not recorded:
                recorded = True
                # read highest score
                with open("record.txt", "r") as f:
                    record_score = int(f.read())

                # save hishest score
                if score > record_score:
                    with open("record.txt", "w") as f:
                        f.write(str(score))

            if record_score > score:
                higher_score = record_score
            else:
                higher_score = score

            # game end interface
            record_score_text = score_font.render("Best : %d" % higher_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()

        #pic switch
        if not (delay % 5):
            switch_image = not switch_image

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Beispiel #11
0
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)
Beispiel #12
0
def main():
#pygame.mixer.music.play(n,start,stop)
#第一个参数为播放次数,如果是-1表示循环播放,省略表示只播放1次。第二个参数和第三个参数分别表示播放的起始和结束位置。
	pygame.mixer.music.play(-1)

	clock = pygame.time.Clock()
#生成我方飞机
	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)

#中弹图片索引
	e1_destroy_index = 0
	e2_destroy_index = 0
	e3_destroy_index = 0
	me_destroy_index = 0

	#统计得分
	score = 0
	score_font = pygame.font.Font(None, 36)

	life_image = pygame.image.load("images/me2.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()
	paused_rect = resume_nor_image.get_rect()
	paused_rect.left, paused_rect.top = width-paused_rect.width-10, 10
	paused_image = resume_nor_image


#生成普通子弹
	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):
		bullet2.append(bullet.Bullet2((me.rect.centerx-20, me.rect.centery)))
		bullet2.append(bullet.Bullet2((me.rect.centerx+20, me.rect.centery)))

	running = True
#用于延迟
	delay = 100

#设置难度等级
	level = 1

	bomb_image = pygame.image.load("images/bomb.png").convert_alpha()
	bomb_rect = bomb_image.get_rect()
	bomb_font = pygame.font.Font(None, 48)
	bomb_num = 3

	#每30s发放一个补给包
	bullet_supply = supply.Bullet_Supply(bg_size)
	bomb_supply = supply.Bomb_Supply(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


	while running:
		for event in pygame.event.get():
			if event.type == QUIT:
#如果用IDLE打开的话,直接关闭窗口的话 无法关闭,加上这个能关闭窗口
				pygame.quit()
				sys.exit()
			elif event.type == MOUSEBUTTONDOWN:
				if event.button == 1 and paused_rect.collidepoint(event.pos):
					paused = not paused
					if paused:
						#发放包设置为0,取消这个事件
						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:
						pass
					else:
						paused_image = pause_nor_image
				else:
					if paused:
						pass
					else:
						paused_image = resume_nor_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:
								each.active = False

			elif event.type == SUPPLY_TIME:
				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)

		screen.blit(background, (0, 0))

		if level == 1 and score > 5000:
			level = 2
			add_big_enemies(big_enemies, enemies, 1)
			add_mid_enemies(mid_enemies, enemies, 2)
			add_small_enemies(small_enemies, enemies, 3)
			inc_speed(small_enemies, 1)

		if level == 2 and score > 6000000:
			level = 3
			add_big_enemies(big_enemies, enemies, 1)
			add_mid_enemies(mid_enemies, enemies, 3)
			add_small_enemies(small_enemies, enemies, 5)
			inc_speed(small_enemies, 1)
			inc_speed(mid_enemies, 1)

		if level == 3 and score > 9000000:
			level = 4
			add_big_enemies(big_enemies, enemies, 1)
			add_mid_enemies(mid_enemies, enemies, 3)
			add_small_enemies(small_enemies, enemies, 5)
			inc_speed(small_enemies, 1)
			inc_speed(mid_enemies, 1)

		if level == 4 and score > 10000000:
			level = 5
			add_big_enemies(big_enemies, enemies, 1)
			add_mid_enemies(mid_enemies, enemies, 3)
			add_small_enemies(small_enemies, enemies, 5)
			inc_speed(small_enemies, 1)
			inc_speed(mid_enemies, 1)

		if life_num and not paused:
			#检测用户的键盘操作 key_pressed包含所有键盘的布尔值
			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):
					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):
					is_double_bullet = True
					pygame.time.set_timer(DOUBLE_BULLET_TIME, 18*1000)
					bullet_supply.active = False

	#发射子弹
			if not(delay % 10):
				if is_double_bullet:
					bullets = bullet2
					bullets[bullet2_index].reset((me.rect.centerx-20, me.rect.centery))
					bullets[bullet2_index].reset((me.rect.centerx+20, me.rect.centery))
					bullet2_index = (bullet2_index+1)%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.energy -= 1
								if e.energy == 0:
									e.active = False
							else:
								e.active = False


	#绘制大型机
			for each in big_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.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 each.rect.bottom < each.height // 2:
						enemy3_down_sound.play(-1)
	#毁灭
				else:
					screen.blit(each.destroy_images[e3_destroy_index], each.rect)
					e3_destroy_index = (e3_destroy_index + 1) % 1
					if e3_destroy_index == 0:
						score += 10000
						each.reset()

	#绘制中型机
			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:
					screen.blit(each.destroy_images[e2_destroy_index], each.rect)
					e2_destroy_index = (e2_destroy_index + 1) % 1
					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:
					screen.blit(each.destroy_images[e1_destroy_index], each.rect)
					e1_destroy_index = (e1_destroy_index + 1) % 1
					if e1_destroy_index == 0:
						score += 1000
						each.reset()
	#检查我方飞机是否被碰撞, 这个函数的第一个参数就是单个精灵,第二个参数是精灵组,第三个参数是一个bool值,当为True的时候,会删除组中所有冲突的精灵,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 me.active:
				screen.blit(me.image, (me.rect.left, me.rect.top))
	#毁灭
			else:
				screen.blit(each.destroy_images[me_destroy_index], each.rect)
				me_destroy_index = (me_destroy_index + 1) % 1
				if me_destroy_index == 0:
					life_num -= 1
					me.reset()
					pygame.time.set_timer(INVINCIBLE_TIME, 3*1000)


#绘制剩余生命的数量
			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)

#绘制全屏炸弹
			bomb_text = bomb_font.render("x %d" % bomb_num, True, WHITE)
			text_bomb = rect = bomb_text.get_rect()
			screen.blit(bomb_image, (10, height-10-bomb_rect.width))
			screen.blit(bomb_text, (20+bomb_rect.width, height-5-text_bomb.height))

			if not delay:
				delay = 100
			delay = delay - 1
			pygame.display.flip()
	#一秒钟页面刷新60次,即60帧,即一次while循环是1帧
			clock.tick(60)
		elif life_num == 0:
			print("GAME OVER!")
			running = False
Beispiel #13
0
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)
Beispiel #14
0
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)))

    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

    #设置难度
    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

    #每一段时间出现补给 supply
    bullet_supply = supply.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 8 * 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

    #用于阻止重复打开记录文件
    recorded = False

    #切换图片
    switch_image = 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()

    #飞机尾气延时
    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, 8 * 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
                        me.invi()
                        pygame.time.set_timer(INVINCIBLE_TIME, 1 * 1000)
            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
            upgrade_sound.play()
            #增加3/2/1架 small_enemy/mid_enemy/big_enemy
            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, 0.5)
        elif level == 2 and score >= 300000:
            level = 3
            upgrade_sound.play()
            #增加4/2/1架 small_enemy/mid_enemy/big_enemy
            add_small_enemies(small_enemies, enemies, 4)
            add_mid_enemies(mid_enemies, enemies, 2)
            add_big_enemies(big_enemies, enemies, 1)
            #提升敌机速度
            inc_speed(small_enemies, 0.5)
            inc_speed(mid_enemies, 0.5)
        elif level == 3 and score >= 600000:
            level = 4
            upgrade_sound.play()
            #增加4/3/1架 small_enemy/mid_enemy/big_enemy
            add_small_enemies(small_enemies, enemies, 4)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_big_enemies(big_enemies, enemies, 1)
            #提升敌机速度
            inc_speed(small_enemies, 0.5)
            inc_speed(mid_enemies, 0.5)
            inc_speed(big_enemies, 0.25)
        elif level == 4 and score >= 1000000:
            level = 5
            upgrade_sound.play()
            #增加5/3/2架 small_enemy/mid_enemy/big_enemy
            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, 0.5)
            inc_speed(mid_enemies, 0.5)
            inc_speed(big_enemies, 0.5)
        #绘制背景background   绘制代码不要随便变动代码位置  背景置底
        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.moveUp()
            if key_pressed[K_a] or key_pressed[K_LEFT]:
                me.moveLeft()
            if key_pressed[K_s] or key_pressed[K_DOWN]:
                me.moveDown()
            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):
                    get_bomb_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):
                    get_bullet_sound.play()
                    #发射超级子弹
                    is_double_bullet = True
                    pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)
                    bullet_supply.active = False

            #发射子弹
            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.energy -= 1
                                e.hit = True
                                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)
                    #当生命大于50%显示绿色 50%-26%显示黄色 25%及以下显示红色
                    energy_remain = each.energy / enemy.BigEnemy.energy
                    if energy_remain > 0.5:
                        energy_color = GREEN
                    elif energy_remain > 0.25:
                        energy_color = YELLOW
                    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_flying_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_flying_sound.stop()
                            score += 50000
                            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)
                    #当生命大于50%显示绿色 50%-26%显示黄色 25%及以下显示红色
                    energy_remain = each.energy / enemy.MidEnemy.energy
                    if energy_remain > 0.5:
                        energy_color = GREEN
                    elif energy_remain > 0.25:
                        energy_color = YELLOW
                    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 += 20000
                            each.reset()
            #绘制敌方飞机 小型机
            for each in small_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)
                    #当生命大于50%显示绿色 50%-26%显示黄色 25%及以下显示红色
                    energy_remain = each.energy / enemy.SmallEnemy.energy
                    if energy_remain > 0.5:
                        energy_color = GREEN
                    elif energy_remain > 0.25:
                        energy_color = YELLOW
                    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 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数量
            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))

        #绘制游戏结束画面
        elif life_num == 0:
            #停止bgm 音效
            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()
                #点击结束游戏
                if gameover_rect.left<pos[0]<gameover_rect.right and \
                   gameover_rect.top<pos[1]<gameover_rect.bottom:
                    pygame.quit()
                    sys.exit()

        #绘制暂停按钮
        if life_num != 0:
            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)
Beispiel #15
0
def main():
    pygame.mixer.music.play(-1)
    # Tạo máy bay
    me = myplane.MyPlane(bg_size)

    enemies = pygame.sprite.Group()

    # tạo kẻ địch 1
    small_enemies = pygame.sprite.Group()
    add_small_enemies(small_enemies, enemies, 15)

    # tạo kẻ địch 2
    mid_enemies = pygame.sprite.Group()
    add_mid_enemies(mid_enemies, enemies, 4)

    # tạo trùm cuối
    big_enemies = pygame.sprite.Group()
    add_big_enemies(big_enemies, enemies, 2)

    # Đạn loại 1
    bullet1 = []
    bullet1_index = 0
    BULLET1_NUM = 4
    for i in range(BULLET1_NUM):
        bullet1.append(bullet.Bullet1(me.rect.midtop))

    # Đạn loại 2
    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)))

    clock = pygame.time.Clock()

    # bị tiêu diệt
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    me_destroy_index = 0

    # Điểm thống kê
    score = 0
    score_font = pygame.font.Font("font/font.ttf", 36)

    # Nút tạm dừng trò chơi
    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

    # độ khó
    level = 2

    # Skill bom
    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 sẽ rót 1 item
    bullet_supply = supply.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

    # Thời gian phát nổ
    DOUBLE_BULLET_TIME = USEREVENT + 1

    is_double_bullet = False

    INVINCIBLE_TIME = USEREVENT + 2

    # Mạng
    life_image = pygame.image.load("images/life.png").convert_alpha()
    life_rect = life_image.get_rect()
    life_num = 3

    # Ngăn ghi nhiều tệp
    recorded = False

    # Sau khi thua
    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()

    # chuyển đổi ảnh
    switch_image = True

    # Độ trễ
    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, 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)

        # Tăng độ khó dựa trên điểm người chơi
        if level == 1 and score > 500:
            level = 2
            upgrade_sound.play()
            # Thêm 3 máy bay địch nhỏ, 2 máy bay địch trung bình và 1 máy bay địch lớn
            add_small_enemies(small_enemies, enemies, 3)
            add_mid_enemies(mid_enemies, enemies, 2)
            add_big_enemies(big_enemies, enemies, 1)
            # Tăng tốc độ của máy bay địch nhỏ
            inc_speed(small_enemies, 1)
        elif level == 2 and score > 6000:
            level = 3
            upgrade_sound.play()
            # Thêm 5 máy bay địch nhỏ, 3 máy bay địch trung bình và 2 máy bay địch lớn
            add_small_enemies(small_enemies, enemies, 10)
            add_mid_enemies(mid_enemies, enemies, 4)
            add_big_enemies(big_enemies, enemies, 1)
            # Tăng tốc độ của máy bay địch nhỏ
            inc_speed(small_enemies, 2)
            inc_speed(mid_enemies, 1)
        elif level == 3 and score > 200000:
            level = 4
            upgrade_sound.play()
            # Thêm 5 máy bay địch nhỏ, 3 máy bay địch trung bình và 2 máy bay địch lớn
            add_small_enemies(small_enemies, enemies, 15)
            add_mid_enemies(mid_enemies, enemies, 6)
            add_big_enemies(big_enemies, enemies, 2)
            # Tăng tốc độ của máy bay địch nhỏ
            inc_speed(small_enemies, 2)
            inc_speed(mid_enemies, 1)
        elif level == 4 and score > 1000000:
            level = 5
            upgrade_sound.play()
            # Thêm 5 máy bay địch nhỏ, 3 máy bay địch trung bình và 2 máy bay địch lớn
            add_small_enemies(small_enemies, enemies, 20)
            add_mid_enemies(mid_enemies, enemies, 9)
            add_big_enemies(big_enemies, enemies, 3)
            # Tăng tốc độ của máy bay địch nhỏ
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)

        screen.blit(background, (0, 0))

        if life_num and not paused:
            # Thao tác di chuyển
            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()

            # Vẽ nguồn cung cấp bom toàn màn hình và kiểm tra xem chúng có lấy đc không(tối đa là 3 nha)
            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

            # Rút nguồn cung cấp đạn 2 và kiểm tra xem chúng có được không
            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

            # Bắn một viên đạn
            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

            # Kiểm tra xem đạn có trúng máy bay địch không
            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

            # Tạo máy bay địch cỡ lớn
            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)

                    # Vẽ thanh máu
                    pygame.draw.line(screen, BLACK, \
                                     (each.rect.left, each.rect.top - 5), \
                                     (each.rect.right, each.rect.top - 5), \
                                     2)
                    # Máu lớn hơn 20% thì xanh ngược lại thì đỏ
                    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)

                    # Xuất hiện sẽ có âm thanh
                    if each.rect.bottom == -50:
                        enemy3_fly_sound.play(-1)
                else:
                    # Âm thanh khi bị tiêu diệt
                    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()

            # Vẽ máy bay địch cỡ trung bình :
            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)

                    # Vẽ thanh máu
                    pygame.draw.line(screen, BLACK, \
                                     (each.rect.left, each.rect.top - 5), \
                                     (each.rect.right, each.rect.top - 5), \
                                     2)
                    # Máu lớn hơn 20% thì xanh ngược lại thì đỏ
                    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:
                    # Âm thanh khi bị tiêu diệt
                    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()

            # Vẽ máy bay địch cỡ nhỏ :
            for each in small_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                else:
                    # Âm thanh khi bị tiêu diệt
                    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()

            # Kiểm tra trúng đạn
            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

            # Tạo máy bay chính
            if me.active:
                if switch_image:
                    screen.blit(me.image1, me.rect)
                else:
                    screen.blit(me.image2, me.rect)
            else:
                # Khi bị tiêu diệt
                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)

            # Rút số lượng skill bom xài
            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))

            # Điểm
            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))

            # Xét
            score_text = score_font.render("Score : %s" % str(score), True,
                                           WHITE)
            screen.blit(score_text, (10, 5))

        # Đưa đến màn hình kết thúc trò chơi
        elif life_num == 0:
            # Nhạc nền
            pygame.mixer.music.stop()

            # Tắt âm
            pygame.mixer.stop()

            # Ngừng cung cấp
            pygame.time.set_timer(SUPPLY_TIME, 0)

            if not recorded:
                recorded = True
                # Đọc điểm cao nhất trong lịch sử
                with open("record.txt", "r") as f:
                    record_score = int(f.read())

                # Nếu điểm của người chơi cao hơn điểm cao nhất trong lịch sử thì lưu
                if score > record_score:
                    with open("record.txt", "w") as f:
                        f.write(str(score))

            # Tạo màn hình kết thúc
            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)

            # Click chuột thì nó sẽ hiểu
            # Nếu người dùng nhấn nút chuột trái
            if pygame.mouse.get_pressed()[0]:
                # Nhận tọa độ chuột
                pos = pygame.mouse.get_pos()
                # Nếu người dùng nhấp vào "Chơi lại"
                if again_rect.left < pos[0] < again_rect.right and \
                        again_rect.top < pos[1] < again_rect.bottom:
                    # Gọi chức năng chính để khởi động lại trò chơi
                    main()
                # Nếu người dùng nhấp vào "among us" thì kết thúc trò chơi
                elif gameover_rect.left < pos[0] < gameover_rect.right and \
                        gameover_rect.top < pos[1] < gameover_rect.bottom:
                    # Thoát game
                    pygame.quit()
                    sys.exit()

                    # Tạo nút pause
        screen.blit(paused_image, paused_rect)

        # Chuyển đổi hình ảnh
        if not (delay % 5):
            switch_image = not switch_image

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Beispiel #16
0
def start():
    # 播放音乐
    pygame.mixer.music.play(-1)

    # 实例我方飞机
    me = myplane.MyPlane(bg_size=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/rough.ttf", 36)

    # 标志是否暂停游戏
    paused = False
    paused_nor_image = pygame.image.load(
        "images/pause_nor.png").convert_alpha()
    paused_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 = 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('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)

    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

    # 超级子弹定时器
    DOUBLE_BULLTET_TIME = USEREVENT + 1

    # 解除我方重生无敌定时器
    INVINCIBLE_TIME = USEREVENT + 2

    # 标志是否使用超级子弹
    is_double_bullet = False

    # 生命数量
    life_image = pygame.image.load('images/life.png').convert_alpha()
    life_rect = life_image.get_rect()
    life_num = 3

    # 用于切换我方飞机图片
    switch_plane = 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()

    # 用于延迟切换
    delay = 100

    # 限制打开一次记录文件
    recorded = False

    clock = pygame.time.Clock()
    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, 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 = paused_pressed_image
                else:
                    if paused:
                        paused_image = resume_nor_image
                    else:
                        paused_image = paused_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_BULLTET_TIME:
                is_double_bullet = False
                pygame.time.set_timer(DOUBLE_BULLTET_TIME, 0)

            elif event.type == INVINCIBLE_TIME:
                me.invincible = False
                pygame.time.set_timer(INVINCIBLE_TIME, 0)

        # 根据用户得分增加难度
        if level == 1 and score > 5000:
            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(target=small_enemies, inc=1)

        elif level == 2 and score > 30000:
            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(target=small_enemies, inc=1)
            inc_speed(target=mid_enemies, inc=1)

        elif level == 3 and score > 60000:
            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(target=small_enemies, inc=1)
            inc_speed(target=mid_enemies, inc=1)

        elif level == 4 and score > 100000:
            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(target=small_enemies, inc=1)
            inc_speed(target=mid_enemies, inc=1)
            inc_speed(target=big_enemies, inc=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.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):
                    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):
                    get_bullet_sound.play()
                    # 发射超级子弹
                    is_double_bullet = True
                    pygame.time.set_timer(DOUBLE_BULLTET_TIME, 18 * 1000)
                    bullet_supply.active = False

            # 发射子弹
            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 each in enemy_hit:
                            each.hit = True
                            each.energy -= 1
                            if each.energy == 0:
                                each.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_plane:
                            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 == -10:
                        enemy3_fly_sound.play(-1)
                        each.appear = True
                    # 离开画面, 关闭音效
                    if each.rect.bottom < -10 and each.appear:
                        enemy3_fly_sound.stop()
                        each.appear = False
                else:
                    # 毁灭
                    if e3_destroy_index == 0:
                        enemy3_down_sound.play()
                    if not (delay % 2):
                        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 += 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)

                    # 当生命大于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 e2_destroy_index == 0:
                        enemy2_down_sound.play()
                    if not (delay % 2):
                        screen.blit(each.destroy_images[e2_destroy_index],
                                    each.rect)
                        e2_destroy_index = (e2_destroy_index + 1) % 4
                        if e2_destroy_index == 0:
                            score += 600
                            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 % 2):
                        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()

            # 检测我方飞机碰撞
            enemies_down = pygame.sprite.spritecollide(
                me, enemies, False, pygame.sprite.collide_mask)
            if enemies_down and not me.invincible:
                me.active = False
                for each in enemies_down:
                    each.active = False

            # 绘制我方飞机
            if me.active:
                if switch_plane:
                    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 % 2):
                    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)
            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 : %d' % 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_scores = f.readlines()

                    record_score = int(record_scores[0])
                    for i in range(0, 10):
                        record_scores[i] = record_scores[i].strip("\n")

                    for i in range(0, 10, 1):
                        if score >= int(record_scores[i]):
                            for j in range(9, i - 1, -1):
                                record_scores[j] = record_scores[j - 1]
                            record_scores[i] = score
                            modify(record_scores)
                            break

            # 绘制结束界面
            record_score_text = score_font.render(
                "Best : %d" % int(record_scores[0]), 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)
            rank_rect.top = gameover_rect.bottom + 10
            screen.blit(rank_image, rank_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()

                elif rank_rect.left < pos[
                        0] < rank_rect.right and rank_rect.top < rank_rect.bottom:
                    rank()

        # 绘制暂停按钮
        screen.blit(paused_image, paused_rect)

        # 用于切换图片
        if not (delay % 11):
            switch_plane = not switch_plane

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Beispiel #17
0
def main():
    pygame.mixer.music.play(-1)

    #帧率设置
    clock = pygame.time.Clock()

    # 中弹图片索引
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    me_destroy_index = 0

    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, 5)

    #生成敌方大飞机
    big_enemies = pygame.sprite.Group()
    add_big_enemies(big_enemies, enemies, 1)

    running = True
    switch_image = True
    delay = 100
    score = 0
    score_font = pygame.font.Font("font/font.ttf", 36)

    bullets = []

    # 生成普通子弹
    bullet1 = []
    bullet1_index = 0
    BULLET1_NUM = 4
    for i in range(BULLET1_NUM):
        bullet1.append(bullet.Bullet1(me.rect.midtop))

    # 生命数量
    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()

    DOUBLE_BULLET_TIME = USEREVENT + 1

    # 解除我方飞机无敌状态
    INVINCEBLE_TIME = USEREVENT + 2

    # 生成超级子弹
    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)))

    # 标记是否使用超级子弹
    is_double_bullet = False

    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.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

    # 阻止重复读取成绩记录文件
    recorded = False

    # 标志是否暂停游戏
    paused = False
    paused_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 = paused_nor_image.get_rect()
    paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
    paused_image = paused_nor_image

    while running:
        for event in pygame.event.get():
            if event.type == pygame.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()
                        paused_image = resume_pressed_image
                    else:
                        pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
                        pygame.mixer.music.unpause()
                        pygame.mixer.unpause()
                        paused_image = pause_pressed_image
            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 = paused_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]):
                    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 == INVINCEBLE_TIME:
                me.invincible = False
                pygame.time.set_timer(INVINCEBLE_TIME, 0)

        # 根据用户的得分增加难度
        if level == 1 and score > 50000:
            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)
            inc_speed(small_enemies, 1)
        elif level == 2 and score > 300000:
            level = 3
            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 > 300000:
            level = 4
            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
            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)

        screen.blit(background, (0, 0))

        if life_num and not paused:
            # 绘制全屏炸弹补给并检测是否获得
            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 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 + 33, 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

            # 绘制全屏炸弹补给并检测是否获得
            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

            # 绘制大型敌机
            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)
                    if each.rect.bottom == -50:
                        enemy3_fly_sound.play(-1)

                    # 绘制血槽
                    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)

                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:
                            me_down_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)
                        each.hit = False
                    else:
                        screen.blit(each.image1, 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:
                            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 += 5000
                            each.reset()

            # 绘制小型敌机
            for each in small_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image1, 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()

            key_pressed = pygame.key.get_pressed()
            if key_pressed[K_w] or key_pressed[K_UP]:
                me.moveUp()
            elif key_pressed[K_s] or key_pressed[K_DOWN]:
                me.moveDown()
            elif key_pressed[K_a] or key_pressed[K_LEFT]:
                me.moveLeft()
            elif key_pressed[K_d] or key_pressed[K_RIGHT]:
                me.moveRight()
            elif key_pressed[K_F1]:
                is_double_bullet = not is_double_bullet

            # 检测我方飞机是否被撞
            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:
                me_down_sound.play()
                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:
                        life_num -= 1
                        me.reset()
                        pygame.time.set_timer(INVINCEBLE_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(str("Score: %s" % 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, 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)

            # 检测用户的鼠标操作
            # 如果用户按下鼠标左键
            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)
        #切换图片
        if not (delay % 5):
            switch_image = not switch_image

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Beispiel #18
0
def main():
    #pygame.mixer.music.play(重复次数,开始时间),这里重复次数会加上原来的一次,开始时间如果为1.0的话,表示从音乐的第2秒开始播放.
    pygame.mixer.music.play(-1)  #这里设置-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_MUN = 6  #6颗子弹
    for i in range(BULLET1_MUN):
        bullet1.append(bullet.Bullet1(me.rect.midtop))  #midtop是顶部中央的意思

    #增强弹药
    bullet2 = []
    bullet2_index = 0  #用于索引
    BULLET2_MUN = 12  #12颗子弹
    for i in range(BULLET2_MUN // 2):
        bullet2.append(bullet.Bullet2((me.rect.centerx - 33, me.rect.centery)))
        bullet2.append(bullet.Bullet2((me.rect.centerx + 30, me.rect.centery)))

    # 中弹图片索引
    e1_des_index = 0
    e2_des_index = 0
    e3_des_index = 0
    me_des_index = 0

    #统计得分
    score = 0
    score_font = pygame.font.Font("font/font.TTF", 36)  #定义字体

    #标志是否暂停游戏
    paused = False
    #加载暂停图片
    stopping_img = pygame.image.load("image/stopping.png").convert_alpha()
    stopping_rect = stopping_img.get_rect()
    stopping_rect.left, stopping_rect.top = width / 2 - stopping_rect.width / 2, height / 2 - stopping_rect.height / 2
    stop1_img = pygame.image.load("image/stop1.png").convert_alpha()
    stop2_img = pygame.image.load("image/stop2.png").convert_alpha()
    begin1_img = pygame.image.load("image/begin1.png").convert_alpha()
    begin2_img = pygame.image.load("image/begin2.png").convert_alpha()
    stop_rect = stop1_img.get_rect()
    begin_rect = begin1_img.get_rect()
    paused_rect = stop1_img.get_rect()
    stop_rect.left, stop_rect.top = width - stop_rect.width - 10, 10
    begin_rect.left, begin_rect.top = width - begin_rect.width - 10, 10
    pause_img = stop1_img  #设置默认图片

    #设置难度级别,默认难度1
    level = 1

    #全屏炸弹
    bomb_img = pygame.image.load("image/boom.jpg").convert_alpha()
    bomb_rect = bomb_img.get_rect()
    bomb_font = pygame.font.Font("font/font.TTF", 48)
    bomb_num = 3  #炸弹数量

    #每30秒发放一个补给56
    bullet_supply = supply.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    #定时器
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

    #弹药增强定时器
    DOUBLE_BULLET_TIME = USEREVENT + 1
    #标志是否使用增强弹药
    is_double_bullet = False

    #生命数量
    life_img = pygame.image.load("image/life.png").convert_alpha()
    life_rect = life_img.get_rect()
    life_num = 3

    running = True
    switch_image = True  #飞机图片切换
    delay = 100  #人工干预延迟

    #解除我方无敌状态计时器
    INVINCIBLE_TIME = USEREVENT + 2

    #用于重复打开文件
    record_file = False

    #用于游戏结束界面
    gameover_font = pygame.font.Font("font/font.TTF", 48)
    gameover_font1 = pygame.font.Font("font/font.TTF", 35)
    again_img = pygame.image.load("image/again.png").convert_alpha()  #再来一次按钮
    again_rect = again_img.get_rect()
    gameover_img = pygame.image.load(
        "image/gameover.png").convert_alpha()  #结束游戏按钮
    gameover_rect = gameover_img.get_rect()
    again_rect.left, again_rect.top = 318 + 65, 424 + 200
    gameover_rect.left, gameover_rect.top = 318, 424 + 300

    #标志是否超过历史最高分
    is_congratulate = False

    #返回主菜单按钮
    comeback1_img = pygame.image.load(
        "image/comeback1.png").convert_alpha()  #返回按钮
    comeback2_img = pygame.image.load("image/comeback2.png").convert_alpha()
    comeback_img = comeback1_img  #设置默认图片
    comeback_rect = comeback1_img.get_rect()
    comeback_rect.left, comeback_rect.top = 901 - 100, 897 - 100

    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

            #检测玩家是否按下了暂停按钮
            elif event.type == MOUSEBUTTONDOWN:
                if life_num:
                    #collidepoint(event.pos),自动检测鼠标是否停留在pos内,如果是则返回True
                    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,
                                                  30 * 1000)  #定时器开始
                            pygame.mixer.music.unpause()  #背景音乐开始
                            pygame.mixer.unpause()  #所有其他音乐特效开始

                if life_num == 0:

                    #检测玩家是否按下了退出游戏按钮
                    if event.button == 1 and gameover_rect.collidepoint(
                            event.pos):
                        pygame.quit()
                        sys.exit()

                    elif event.button == 1 and again_rect.collidepoint(
                            event.pos):
                        main()

                    elif event.button == 1 and comeback_rect.collidepoint(
                            event.pos):
                        menu_sound.play()
                        Menu()

            #检测鼠标是否移动到暂停游戏按钮
            elif event.type == MOUSEMOTION:
                if life_num == 0:
                    if event.type == MOUSEMOTION:
                        if comeback_rect.collidepoint(event.pos):
                            comeback_img = comeback1_img
                        else:
                            comeback_img = comeback2_img
                else:
                    if paused_rect.collidepoint(event.pos):
                        if paused:
                            pause_img = begin2_img
                            paused_rect = begin_rect
                        else:
                            pause_img = stop2_img
                            paused_rect = stop_rect
                    else:
                        if paused:
                            pause_img = begin1_img
                            paused_rect = begin_rect
                        else:
                            pause_img = stop1_img
                            paused_rect = stop_rect

            #引爆炸弹
            elif event.type == KEYDOWN:
                if event.key == K_SPACE:
                    if bomb_num:
                        bomb_num -= 1
                        bomb.play()
                        for each in enemies:
                            if each.rect.bottom > 0:
                                each.active = False

            #规定时间发放补给56
            elif event.type == SUPPLY_TIME:
                supply_sound.play()
                if choice([False, True]):
                    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)

        #根据玩家得分增加难度
        #提升到难度2
        if level == 1 and score >= 300:
            level = 2
            up_level.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)
        #提升到难度3
        elif level == 2 and score >= 800:
            level = 3
            up_level.play()
            #增加5架小敌机,3架中敌机和1架大敌机
            add_small_enemies(small_enemies, enemies, 5)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_big_enemies(big_enemies, enemies, 1)
            #提升敌机的速度
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)
        #提升到难度4
        elif level == 3 and score >= 1500:
            level = 4
            up_level.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)
            inc_speed(big_enemies, 1)
        #提升到难度5
        elif level == 4 and score >= 2500:
            level = 5
            up_level.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)
            inc_speed(big_enemies, 1)

        screen.blit(background, (0, 0))  #显示背景

        if paused:
            #显示暂停时的界面
            screen.blit(stopping_img, stopping_rect)
            screen.blit(pause_img, paused_rect)
            #显示分数,Ture表示不显示锯齿
            score_text = score_font.render("Score : %s" % str(score), True,
                                           WHITE)
            screen.blit(score_text, (10, 5))  #在页面左上角显示分数

        if life_num 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()

            #绘制炸弹补给并检测玩家是否获得补给56
            if bomb_supply.active:
                bomb_supply.move()
                screen.blit(bomb_supply.image, bomb_supply.rect)
                if pygame.sprite.collide_mask(bomb_supply,
                                              me):  #检测我方飞机是否与补给非透明部分碰撞
                    get_supply.play()
                    if bomb_num < 3:
                        bomb_num += 1
                    bomb_supply.active = False

            #绘制子弹补给并检测玩家是否获得补给56
            if bullet_supply.active:
                bullet_supply.move()
                screen.blit(bullet_supply.image, bullet_supply.rect)
                if pygame.sprite.collide_mask(bullet_supply,
                                              me):  #检测我方飞机是否与补给非透明部分碰撞
                    bullet_supply.active = False
                    get_supply.play()
                    is_double_bullet = True
                    pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)

            #发射子弹
            if not (delay % 10):
                #播放子弹的声音
                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_MUN
                else:
                    bullets = bullet1
                    bullets[bullet1_index].reset(me.rect.midtop)
                    bullet1_index = (bullet1_index + 1) % BULLET1_MUN

            #检测子弹是否击中敌机
            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:
                            e.hit = True
                            e.energy -= 1
                            if e in mid_enemies or big_enemies:
                                if not e.energy:
                                    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)
                    #当生命大于30%时显示绿色血条,否则显示红色
                    energy_remain = each.energy / enemy.BigEnemy.energy
                    if energy_remain > 0.3:
                        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:
                        big_enemy.play(-1)
                else:
                    #毁灭
                    if not (delay % 3):
                        if e3_des_index == 0:
                            big_die.play()  #播放死亡音效
                        screen.blit(each.destroy_images[e3_des_index],
                                    each.rect)
                        e3_des_index = (e3_des_index + 1) % 6
                        if e3_des_index == 0:
                            big_enemy.stop()
                            score += 100
                            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)
                    #当生命大于30%显示绿色,否则显示红色
                    energy_remain = each.energy / enemy.MidEnemy.energy
                    if energy_remain > 0.3:
                        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_des_index == 0:
                            big_die.play()  #播放死亡音效
                        screen.blit(each.destroy_images[e2_des_index],
                                    each.rect)
                        e2_des_index = (e2_des_index + 1) % 4
                        if e2_des_index == 0:
                            score += 60
                            each.reset()

            #绘制小型敌机
            for each in small_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                else:
                    #毁灭
                    #big_die.play()#播放死亡音效
                    if not (delay % 3):
                        screen.blit(each.destroy_images[e1_des_index],
                                    each.rect)
                        e1_des_index = (e1_des_index + 1) % 4
                        if e1_des_index == 0:
                            score += 10
                            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:
                screen.blit(me.image, me.rect)
            else:
                #毁灭
                #big_die.play()#播放死亡音效
                if not (delay % 3):
                    if me_des_index == 0:
                        big_die.play()
                    screen.blit(me.destroy_images[me_des_index], me.rect)
                    me_des_index = (me_des_index + 1) % 5
                    if me_des_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_img, (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_img,
                                (width - 10 - (i + 1) * life_rect.width,
                                 height - 10 - life_rect.height))

            #显示分数,Ture表示不显示锯齿
            score_text = score_font.render("Score : %s" % str(score), True,
                                           WHITE)
            screen.blit(score_text, (10, 5))  #在页面左上角显示分数

            #绘制暂停按钮
            #print(paused_rect)
            screen.blit(pause_img, (797, 10))

            #控制延迟切换图片
            if not (delay % 5):
                switch_image = not switch_image

            delay -= 1
            if not delay:
                delay = 100

        #绘制游戏结束界面
        elif life_num == 0:
            #背景音乐停止
            pygame.mixer.music.stop()
            #停住全部音效
            pygame.mixer.stop()
            #停止发放补给
            pygame.time.set_timer(SUPPLY_TIME, 0)

            if not record_file:
                record_file = True
                #读取历史最高分
                with open("record.txt", "r") as f:
                    record_score = int(f.read())
                if score > record_score:
                    img_num = randint(1, 322)
                    img_num1 = "image2/" + str(img_num) + ".jpg"
                    #print(img_num1)
                    with open(img_num1, "rb") as g:
                        img_data = g.read()
                    with open("img_num1.jpg", "wb") as g:
                        g.write(img_data)
                    score_best = gameover_font.render(
                        "Best Score: %s" % str(score), True, WHITE)
                    congratulate = gameover_font1.render(
                        "Congratulations on your record!", True, WHITE)
                    is_congratulate = True  #标志是否超过历史最高分
                    con_rect = congratulate.get_rect()
                    con_rect.left, con_rect.top = 264 - 50, 486 - 200
                    #print(con_rect.left, con_rect.top)264 486
                    #将记录保存到文件中
                    with open("record.txt", "w") as f:
                        f.write(str(score))
                else:
                    score_best = gameover_font.render(
                        "Best Score: %s" % str(record_score), True, WHITE)
                gameover_text = gameover_font.render("Game over!", True, WHITE)
                gameover_text_rect = gameover_text.get_rect()
                gameover_text_rect.left, gameover_text_rect.top = 318, 424
            #print(gameover_text_rect.left, gameover_text_rect.top)318 424
            your_score = gameover_font.render("Your Score: %s" % str(score),
                                              True, WHITE)
            #绘制结束画面
            if is_congratulate:
                screen.blit(congratulate, con_rect)
            screen.blit(again_img, again_rect)
            screen.blit(gameover_img, gameover_rect)
            screen.blit(score_best, (20, 20))
            screen.blit(your_score, (20, 80))
            screen.blit(gameover_text, gameover_text_rect)
            screen.blit(comeback_img, comeback_rect)

        pygame.display.flip()

        clock.tick(60)
Beispiel #19
0
def main():
    level = 1  # 设置难度级别
    pygame.mixer.music.play(-1)  # 背景音乐

    score = 0  # 统计得分情况
    score_font = pygame.font.Font("ziti/segoeuii.ttf", 36)

    paused = False  ##是否暂停
    pause_nor_image = pygame.image.load(
        "imagess/pause_nor.png").convert_alpha()
    pause_pressed_image = pygame.image.load(
        "imagess/pause_pressed.png").convert_alpha()
    resume_nor_image = pygame.image.load(
        "imagess/resume_nor.png").convert_alpha()
    resume_pressed_image = pygame.image.load(
        "imagess/resume_pressed.png").convert_alpha()
    pause_rect = pause_nor_image.get_rect()
    pause_rect.right, pause_rect.top = width - 10, 10
    pause_image = pause_nor_image

    #全屏炸弹个数显示
    bomb_image = pygame.image.load("imagess/bomb.png")
    bomb_rect = bomb_image.get_rect()
    bomb_fount = pygame.font.Font("ziti/segoeuii.ttf", 36)
    bomb_num = 3
    # 英雄剩余生命
    hero_image = pygame.image.load("imagess/hero3.png").convert_alpha()
    hero_rect = hero_image.get_rect()
    myplane_num = 3

    #每30秒补给包定时器
    bullet_supply = supply.Bullet_supply(bg_size)
    bomb_supply = supply.Bomb_supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

    #超级子弹定时器
    DOUBLE_TIME = USEREVENT + 1
    is_double_bullet = False
    #复活3秒无敌模式定时器
    LNVINCIBLE_TIME = USEREVENT + 2
    lnvincible_mode = False

    #生成我方飞机
    me = myplane.MyPlane(bg_size)
    #生成敌机精灵
    enemies = pygame.sprite.Group()
    #生成小型飞机
    small_enemies = pygame.sprite.Group()
    add_small_enemies(small_enemies, enemies, 20)
    #生成中型飞机
    mid_enemies = pygame.sprite.Group()
    add_mid_enemies(mid_enemies, enemies, 10)
    #生成大型飞机
    big_enemies = pygame.sprite.Group()
    add_big_enemies(big_enemies, enemies, 5)
    #生成子弹

    bullet_active = True  #允许发射子弹
    bullet1 = []
    bullet1_index = 0
    BULLET1_NUM = 4
    for i in range(BULLET1_NUM):
        bullet1.append(bullet.Bullet1(me.rect.midtop))
    bullets = bullet1
    #生成超级子弹
    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 + 33, me.rect.centery)))

    #中弹图片索引
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    me_destroy_index = 0

    # 用于切换英雄飞行图片
    switch_image = True
    delay = 100
    #用于阻止重复打开记录文件
    recorded = False

    #结束游戏画面
    restart_image = pygame.image.load(
        "imagess/restart.png").convert_alpha()  #重新开始图片
    restart_rect = restart_image.get_rect()
    restart_rect.centerx = width / 2
    restart_rect.centery = height / 2
    gameover_image = pygame.image.load(
        "imagess/gameover.png").convert_alpha()  #游戏结束图片
    gameover_rect = gameover_image.get_rect()
    gameover_rect.centerx = width / 2
    gameover_rect.centery = height / 2 + 80

    clock = pygame.time.Clock()
    """主循环"""
    while True:
        screen.blit(background, bg_rect)  #绘制背景
        screen.blit(background, (bg_rect.x, bg_rect.y - 700))  # 绘制背景
        if bg_rect.y >= 700:
            bg_rect.y = 0

        for event in pygame.event.get():  # 事件监听
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            elif event.type == MOUSEBUTTONDOWN:
                if event.button == 1:  #左键单击
                    if 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)
                    elif gameover_rect.collidepoint(event.pos):  #退出游戏
                        if myplane_num <= 0:
                            pygame.quit()
                            sys.exit()
                    elif restart_rect.collidepoint(event.pos):  #重新开始
                        if myplane_num <= 0:
                            main()

            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 > -10:
                                each.active = False

            elif event.type == SUPPLY_TIME:  #发放补给
                supply_sound.play()
                if random.choice([True, False]):  #这里要写成字典
                    bomb_supply.reset()
                else:
                    bullet_supply.reset()

            elif event.type == DOUBLE_TIME:
                is_double_bullet = False
                pygame.time.set_timer(DOUBLE_TIME, 0)

            elif event.type == LNVINCIBLE_TIME:
                lnvincible_mode = False

        #根据得分情况增加游戏难度
        if level == 1 and score >= 500:
            level = 2
            upgrade_sound.play()
            add_small_enemies(small_enemies, enemies, 6)
            add_mid_enemies(mid_enemies, enemies, 4)
            add_big_enemies(big_enemies, enemies, 2)

        elif level == 2 and score >= 3000:
            level = 3
            upgrade_sound.play()
            add_small_enemies(small_enemies, enemies, 8)
            add_mid_enemies(mid_enemies, enemies, 6)
            add_big_enemies(big_enemies, enemies, 3)
            # 提升敌机速度
            inc_speed(small_enemies, 1)

        elif level == 3 and score >= 5000:
            level = 4
            upgrade_sound.play()
            add_small_enemies(small_enemies, enemies, 9)
            add_mid_enemies(mid_enemies, enemies, 7)
            add_big_enemies(big_enemies, enemies, 4)
            # 提升敌机速度
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)

        elif level == 4 and score >= 10000:
            level = 5
            upgrade_sound.play()
            add_small_enemies(small_enemies, enemies, 10)
            add_mid_enemies(mid_enemies, enemies, 8)
            add_big_enemies(big_enemies, enemies, 4)
            # 提升敌机速度
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)

        elif level == 5 and score >= 20000:
            level = 6
            upgrade_sound.play()
            add_small_enemies(small_enemies, enemies, 12)
            add_mid_enemies(mid_enemies, enemies, 10)
            add_big_enemies(big_enemies, enemies, 5)
            # 提升敌机速度
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)
            inc_speed(big_enemies, 1)

        #绘制游戏难度
        pygame.draw.line(screen, BLACK, (5, 600), (5, 100), 2)
        pygame.draw.line(screen, RED, (5, 600), (5, 600 - 100 * (level - 1)),
                         2)

        if not paused and myplane_num > 0:
            keys_pressed = pygame.key.get_pressed()
            if keys_pressed[pygame.K_UP]:  # 上
                me.movup()
            elif keys_pressed[pygame.K_DOWN]:  # 下
                me.movdown()
            elif keys_pressed[pygame.K_LEFT]:  # 左
                me.movleft()
            elif keys_pressed[pygame.K_RIGHT]:  # 右
                me.movright()

            bg_rect.y += 1  #背景图片运动

            #每10针发射一颗子弹
            if not (delay % 15):
                if is_double_bullet:
                    bullets = bullet2
                    bullet2[bullet2_index].reset(
                        (me.rect.centerx - 33, me.rect.centery))
                    bullet2[bullet2_index + 1].reset(
                        (me.rect.centerx + 33, me.rect.centery))
                    bullet2_index = (bullet2_index + 2) % BULLET1_NUM

                else:
                    bullets = bullet1
                    bullet1[bullet1_index].reset(me.rect.midtop)
                    bullet1_index = (bullet1_index + 1) % BULLET1_NUM

            #检测子弹是否击中敌机
            for b in bullets:
                if b.active:
                    b.mov()
                    if bullet_supply:
                        screen.blit(b.image, b.rect)
                    else:
                        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.energy -= 1
                                if e.energy <= 0:
                                    e.active = False
                            else:
                                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)
                    # 生命大于30%显示绿色血条,否则为红色
                    energy_remain = each.energy / enemy.BigEnemy.energy
                    if energy_remain > 0.2:
                        energy_colour = GREEN
                    else:
                        energy_colour = RED
                    pygame.draw.line(screen, energy_colour, \
                                     (each.rect.left, each.rect.top - 5), \
                                     (each.rect.left + each.rect.width* energy_remain , each.rect.top - 5), 2)

                    #播放大飞机飞行音效
                    if each.rect.bottom == 0:
                        enemy3_fly_sound.play()

                else:  #大飞机毁灭

                    if not (delay % 3):
                        if e3_destroy_index == 0:
                            enemy3_die_sound.play()
                        screen.blit(each.destroy_images[e3_destroy_index],
                                    each.rect)
                        e3_destroy_index = (e3_destroy_index + 1) % 7
                        if e3_destroy_index == 0:
                            score += 100
                            each.reset()
                            enemy3_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)
                    # 生命大于30%显示绿色血条,否则为红色
                    energy_remain = each.energy / enemy.MidEnemy.energy
                    if energy_remain > 0.2:
                        energy_colour = GREEN
                    else:
                        energy_colour = RED
                    pygame.draw.line(screen, energy_colour, \
                                     (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_die_sound.play()
                        screen.blit(each.destroy_images[e2_destroy_index],
                                    each.rect)
                        e2_destroy_index = (e2_destroy_index + 1) % 5
                        if e2_destroy_index == 0:
                            score += 60
                            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_die_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 += 10
                            each.reset()

            #绘制补给包
            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_bomb_sound.play()
                    bullet_supply.active = False
                    #发射超级子弹
                    pygame.time.set_timer(DOUBLE_TIME, 20 * 1000)
                    is_double_bullet = True

            if not lnvincible_mode:
                #检测我方飞机是否被撞
                enemies_down = pygame.sprite.spritecollide(
                    me, enemies, False, pygame.sprite.collide_mask)
                if enemies_down:
                    for e in enemies_down:
                        if e.active:
                            me.active = False
                            bomb_num = 3
                            e.active = False
                            is_double_bullet = False

            if myplane_num > 0:
                for i in range(myplane_num):
                    screen.blit(hero_image,
                                (width - 10 - hero_rect.width *
                                 (i + 1), height - hero_rect.height - 10))
                # 绘制我方飞机
                if not lnvincible_mode:
                    if not (delay % 5):  # 切换图片
                        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:
                                myplane_num -= 1
                                me.reset()
                                lnvincible_mode = True
                                pygame.time.set_timer(USEREVENT + 2, 4000)

                else:  #无敌状态下
                    if not (delay % 2):  # 切换图片
                        screen.blit(me.image1, me.rect)

        if myplane_num > 0:
            score_text = score_font.render("Score : %s" % str(score), True,
                                           RED)
            screen.blit(score_text, (10, 5))  # 分数显示
            screen.blit(pause_image, pause_rect)  # 显示暂停按钮

            bomb_text = score_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 + text_rect.width),
                                    (height - text_rect.height - 10)))

        else:  #绘制结束游戏画面

            screen.blit(restart_image, restart_rect)
            screen.blit(gameover_image, gameover_rect)
            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))
            # 分数显示
            yourscore_text = score_font.render("Your Score : %s" % str(score),
                                               True, RED)
            screen.blit(yourscore_text, (80, 200))
            record_score_text = score_font.render(
                "Best Score : %s" % record_score, True, RED)
            screen.blit(record_score_text, (80, 260))

        pygame.display.flip()
        delay -= 1
        if not delay:
            delay = 100
        clock.tick(50)
Beispiel #20
0
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, 4)
    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  # 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)))#从炮筒射击
    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)#加载36号字体
    paused=False#暂停标志
    paused_nor_image=pygame.image.load("images/pause_nor.png").convert_alpha()
    paused_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=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("images/bomb.png").convert_alpha()#全屏炸弹
    bomb_rect=bomb_image.get_rect()
    bomb_font=pygame.font.Font("font/font.ttf",48)#48号字体
    bomb_num=3
    bullet_supply=supply.Bullet_Supply(bg_size)#每30秒发放一个补给包
    bomb_supply=supply.Bomb_Supply(bg_size)#实例化
    SUPPLY_TIME=USEREVENT#自定义事件
    pygame.time.set_timer(SUPPLY_TIME,30*1000)#30秒
    DOUBLE_BULLET_TIEM=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#生命数量
    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#用于切换me1.png和me2.png
    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,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=paused_pressed_image
                else:
                    if paused:
                        paused_image=resume_nor_image
                    else:
                        paused_image=paused_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]):#在true和false中选择一个
                    bomb_supply.reset()
                else:
                    bullet_supply.reset()
            elif event.type==DOUBLE_BULLET_TIEM:
                is_double_bullet=False
                pygame.time.set_timer(DOUBLE_BULLET_TIEM,0)#取消定时器
            elif event.type==INVINCIBLE_TIME:
                me.invincible=False
                pygame.time.set_timer(INVINCIBLE_TIME,0)#解除无敌
        if level==1 and score>30:
            level=2#根据得分增加难度
            upgrade_sound.play()
            add_small_enemies(small_enemies,enemies,4)#增加4架小敌机
            add_mid_enemies(mid_enemies,enemies,3)#增加3架中敌机
            add_big_enemies(big_enemies,enemies,1)#增加一架大敌机
            inc_speed(small_enemies,2)#提升小敌机的速度
        elif level==2 and score>100:
            level=3#根据得分增加难度
            upgrade_sound.play()
            add_small_enemies(small_enemies,enemies,5)#增加5架小敌机
            add_mid_enemies(mid_enemies,enemies,4)#增加4架中敌机
            add_big_enemies(big_enemies,enemies,2)#增加2架大敌机
            inc_speed(small_enemies,2)#提升小敌机的速度
            inc_speed(mid_enemies, 2)  # 提升中敌机的速度
        elif level==3 and score>300:
            level=4#根据得分增加难度
            upgrade_sound.play()
            add_small_enemies(small_enemies,enemies,6)#增加6架小敌机
            add_mid_enemies(mid_enemies,enemies,5)#增加5架中敌机
            add_big_enemies(big_enemies,enemies,3)#增加3架大敌机
            inc_speed(small_enemies,2)#提升小敌机的速度
            inc_speed(mid_enemies, 2)  # 提升中敌机的速度
            inc_speed(big_enemies, 2)  # 提升大敌机的速度
        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.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):#检测碰撞
                    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_TIEM,18*1000)#18秒的使用时间
                    bullet_supply.active=False
            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  # 指向下一个索引,不能超过8
                else:
                    bullets=bullet1
                    bullets[bullet1_index].reset(me.rect.midtop)#发射子弹
                    bullet1_index=(bullet1_index+1)%bullet1_NUM#指向下一个索引,不能超过4
            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#每次击中减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)#绘制血槽
                    energy_remain=each.energy/enemy.BigEnemy.energy
                    if energy_remain>0.2:#如果生命大于20%显示绿色,否则显示红色
                        enemies_color=GREEN
                    else:
                        enemies_color=RED
                    pygame.draw.line(screen,enemies_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+=100
                            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)  # 绘制血槽
                    energy_remain = each.energy / enemy.MidEnemy.energy
                    if energy_remain > 0.2:  # 如果生命大于20%显示绿色,否则显示红色
                        enemies_color = GREEN
                    else:
                        enemies_color = RED
                    pygame.draw.line(screen, enemies_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+=10
                            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+=1
                            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)#3秒无敌
            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, WHITE)# 绘制结束画面
            screen.blit(record_score_text, (10, 5))
            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)
            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)#绘制暂停图片
        if not (delay%5):#切换图片
            switch_image=not switch_image
        delay-=1
        if not delay:
            delay=100
        pygame.display.flip()
        clock.tick(60)#60帧
Beispiel #21
0
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))

    clock = pygame.time.Clock()

    # 中弹图片索引
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    me_destroy_index = 0

    # 用于切换图片
    switch_image = True

    # 用于延迟
    delay = 100

    running = True

    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        # 检测用户的键盘操作
        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()

        screen.blit(background, (0, 0))

        # 发射子弹
        if not (delay % 10):
            bullet1[bullet1_index].reset(me.rect.midtop)
            bullet1_index = (bullet1_index + 1) % BULLET1_NUM

        # 检测子弹是否击中敌机
        for b in bullet1:
            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()
                        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:
                        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:
                        each.reset()

        # 检测我方飞机是否被撞
        enemies_down = pygame.sprite.spritecollide(me, enemies, False,
                                                   pygame.sprite.collide_mask)
        if enemies_down:
            # 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:
                    print("Game Over!")
                    running = False

        # 切换图片
        if not (delay % 5):
            switch_image = not switch_image

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Beispiel #22
0
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)
Beispiel #23
0
    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
Beispiel #24
0
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)))

    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

    # �����Ѷȼ���
    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.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(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

    # ������ֹ�ظ��򿪼�¼�ļ�
    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 == 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, 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
            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 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()

            # ����ȫ��ը������������Ƿ���
            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 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)
                        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 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)
            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���������¿�ʼ��Ϸ
                    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)

        # �л�ͼƬ
        if not(delay % 5):
            switch_image = not switch_image

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Beispiel #25
0
def main():
    life_image = pygame.image.load("image/life.png").convert()
    life_rect = life_image.get_rect()
    life_num = 5
    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()
    score = 0
    score_font = pygame.font.SysFont("arial", 48)
    level = 1
    bomb_num = 3
    supply_timer = USEREVENT
    pygame.time.set_timer(supply_timer, 10 * 1000)
    bullet_supply = supply.BulletSupply(bg_size)
    bomb_supply = supply.Bombsupply(bg_size)
    bullet1 = []
    bullet1_index = 0
    bullet1_num = 6
    bullet2 = []
    bullet2_index = 0
    bullet2_num = 10
    is_double_bullet = False
    flag_recorded = False
    double_bullet_timer = USEREVENT + 1
    invincible_time = USEREVENT + 2
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    me_destroy_index = 0
    color_black = (0, 0, 0)
    color_green = (0, 255, 0)
    color_red = (255, 0, 0)
    color_white = (255, 255, 255)
    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)
    me = myplane.MyPlane(bg_size)
    bomb_image = pygame.image.load("image/bomb.png")
    bomb_rect = bomb_image.get_rect()
    bomb_front = score_font
    for i in range(bullet1_num):
        bullet1.append(bullet.Bullet1(me.rect.midtop))
    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)))
    switch_image = False
    delay = 60
    pygame.mixer.music.play(-1)
    running = True
    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))
        screen.blit(paused_image, paused_rect)
        for event in pygame.event.get():
            if 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 == 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 == 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()
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        if life_num and (not paused):
            for i in range(life_num):
                screen.blit(life_image,
                            (width - 10 - (i + 1) * life_rect.width,
                             height - 10 - life_rect.height))
            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 level == 1 and score > 5000:
                level = 2
                level_up_sound.play()
                add_small_enemies(small_enemies, enemies, 1)
                add_mid_enemies(mid_enemies, enemies, 1)
                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, 1)
                add_mid_enemies(mid_enemies, enemies, 1)
                add_big_enemies(big_enemies, enemies, 1)
                inc_speed(small_enemies, 1)
                inc_speed(mid_enemies, 1)
            elif level == 3 and score > 50000:
                level = 4
                level_up_sound.play()
                add_small_enemies(small_enemies, enemies, 1)
                add_mid_enemies(mid_enemies, enemies, 1)
                add_big_enemies(big_enemies, enemies, 1)
                inc_speed(small_enemies, 1)
                inc_speed(mid_enemies, 1)
                inc_speed(big_enemies, 1)
            if not (delay % 20):
                bullet_sound.play()
                if not is_double_bullet:
                    bullets = bullet1
                    bullets[bullet1_index].reset(me.rect.midtop)
                    bullet_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
            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
            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, 18 * 1000)
            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 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()
            for each in mid_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                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 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.5:
                        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 - 2))
                    if each.rect.bottom == -50:
                        big_enemy_flying_sound.play(-1)
                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 += 6000
                            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
            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 delay == 0:
                delay = 60
            delay -= 1
        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:
                with open("score_record.txt", "r") as f:
                    record_score = int(f.read())
                    flag_recorded = True
            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.time.Clock().tick(60)
        pygame.display.flip()
Beispiel #26
0
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)
Beispiel #27
0
def run():
    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)))

    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

    # 设置难度级别
    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.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(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 = 300

    # 用于阻止重复打开记录文件
    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 == QUIT:
                pygame.quit()
                trigger_server.conn.close()#设置socket断开
                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, 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
            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 and not paused:
            # 检测用户的键盘操作和肌电识别程序传来的trigger
            key_pressed = pygame.key.get_pressed()

            trigger = trigger_server.get_trigger()
            #print(trigger)

            if key_pressed[K_w] or key_pressed[K_UP] or trigger == T_UP:
                me.moveUp(SPEED)
            if key_pressed[K_s] or key_pressed[K_DOWN] or trigger == T_DOWN:
                me.moveDown(SPEED)
            if key_pressed[K_a] or key_pressed[K_LEFT] or trigger == T_LEFT:
                me.moveLeft(SPEED)
            if key_pressed[K_d] or key_pressed[K_RIGHT] or trigger == T_RIGHT:
                me.moveRight(SPEED)
            # 避免飞机向一个方向飞到底,及时将trigger置零
            trigger_server.set_trigger(NONE)

            # 绘制全屏炸弹补给并检测是否获得
            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 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)
                        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 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)
            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函数,重新开始游戏
                    main()
                # 如果用户点击“结束游戏”
                elif gameover_rect.left < pos[0] < gameover_rect.right and \
                     gameover_rect.top < pos[1] < gameover_rect.bottom:
                    # 退出游戏
                    pygame.quit()
                    trigger_server.conn.close()#设置socket断开
                    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)
Beispiel #28
0
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)))

	clock = pygame.time.Clock()
	running = True #用于主循环
	switch_image = True #用于切换图片
	delay = 100 #用于延迟
	#中弹索引
	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
	paused_nor_image = pygame.image.load("images\\pause_nor.png").convert_alpha()
	paused_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 = paused_nor_image.get_rect()
	paused_rect.left,paused_rect.top = width - paused_rect.width - 10 ,10  #设置暂停按钮位置
	paused_image = paused_nor_image

	#游戏结束画面
	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()


	#设置游戏级别
	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.Bullet_Supply(bg_size)
	bomb_supply = supply.Bomb_Supply(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

	#用于阻止重复打开记录文件record.txt
	recorded = False
	#用于结束游戏是隐藏暂停按钮
	BUTTON_ON = 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,3 * 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 = paused_pressed_image
				else:
					if paused:
						paused_image = resume_nor_image
					else:
						paused_image = paused_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 > 5000:
			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)
		elif level == 5 and score > 5000000:
			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))	#绘制背景,把绘制背景放到前面,在暂停是遮挡换面,防作弊

		#有剩余生命(life_num不为零) 和 没有暂停执行子循环
		if life_num 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()

			#绘制全屏炸弹补给并检查是否获得
			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整除 调用一次,相当于没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   #被击中时为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.left,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) #-1循环播放
				else:
					if e3_destroy_index == 0:
						#播放销毁图片及音效
						enemy3_down_sound.play()
					#active = False 时毁灭飞机;
					#delay % 3 是 取模余3是进延迟播放
					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:
							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)
						each.hit = False
					else:
						screen.blit(each.image,each.rect)

					#绘制血槽
					pygame.draw.line(screen,BLACK,\
						(each.rect.left,each.rect.top - 5),\
						(each.rect.left,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 e2_destroy_index == 0:
						#active = False 时毁灭飞机;播放销毁图片及音效
						enemy2_down_sound.play()
					#delay % 3 是 取模余3是进延迟播放
					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 += 6000 #在敌机销毁时加分数
							each.reset()  #重置位置


			#绘制小型飞机
			for each in small_enemies:
				if each.active:
					each.move()
					screen.blit(each.image,each.rect)
				else:
					if e1_destroy_index == 0:
						#active = False 时毁灭飞机;播放销毁图片及音效
						enemy1_down_sound.play()
					#delay % 3 是 取模余3是进延迟播放
					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 += 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:
				#active = False 时毁灭飞机;播放销毁图片及音效
				me_down_sound.play()
				#delay % 3 是 取模余3是进延迟播放
				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)

			#绘制炸弹数量
			bomb_text = bomb_font.render("x %d"% bomb_num,True,WHITE)
			text_rect = bomb_image.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)
			#隐藏暂停按钮
			BUTTON_ON = False

			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:%s"%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//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 - 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:
					pygame.quit()
					sys.exit()

		#绘制暂停按钮
		if BUTTON_ON:
			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)				#每秒60帧
Beispiel #29
0
def main():
    pygame.mixer.music.play(-1)

    #生成我方飞机
    me = myplane.MyPlane(bg_size)

    # 生成敌方飞机
    enemies = pygame.sprite.Group()

    # 生成大飞机
    big_enemies = pygame.sprite.Group()
    add_big_enemies(big_enemies, enemies, enemy3_num)

    # 生成中飞机
    mid_enemies = pygame.sprite.Group()
    add_mid_enemies(mid_enemies, enemies, enemy2_num)

    # 生成小飞机
    small_enemies = pygame.sprite.Group()
    add_small_enemies(small_enemies, enemies, enemy1_num)

    # 生成普通子弹
    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)))

    # 用户切换图片
    switch = True

    # 用于延迟
    delay = 100

    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()
    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 = 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', 40)
    bomb_num = 3

    # 每30秒发放一个补给包
    bullet_supply = supply.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)

    # 超级子弹定时器
    DOUBLE_BULLET_TIME = USEREVENT + 1

    # 是否使用超级子弹
    is_double_bullet = False

    # 生命数量
    life_image = pygame.image.load('images/life.png').convert_alpha()
    life_rect = life_image.get_rect()
    life_num = 3

    #  无敌时间计时器
    INVINCIBLE_TIME = USEREVENT + 2

    # 防止重复打开记录文件
    recorded = False

    running = True

    # 是否播放大飞机fly的音效
    play_fly_sound = False

    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.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 not paused and 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

            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 > 50:
            level = 2
            update_sound.play()
            # 增加
            add_small_enemies(small_enemies, enemies, 2)
            add_mid_enemies(mid_enemies, enemies, 1)
            add_big_enemies(big_enemies, enemies, 1)
        elif level == 2 and score > 200:
            level = 3
            update_sound.play()
            # 增加
            add_small_enemies(small_enemies, enemies, 2)
            add_mid_enemies(mid_enemies, enemies, 2)
            add_big_enemies(big_enemies, enemies, 0)
            #提升速度
            increase_speed(small_enemies, 1)
        elif level == 3 and score > 500:
            level = 4
            update_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(mid_enemies, 1)
        elif level == 4 and score > 1200:
            level = 5
            update_sound.play()
            # 增加
            add_small_enemies(small_enemies, enemies, 3)
            add_mid_enemies(mid_enemies, enemies, 1)
            add_big_enemies(big_enemies, enemies, 1)
            #提升速度
            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.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):
                    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 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:
                enemies_hit = []
                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:
                        e.hit = True
                        if e in mid_enemies or e in big_enemies:
                            e.energy -= 1
                            if e.energy == 0:
                                e.active = False
                        else:
                            e.active = False

            # 绘制大飞机
            # 一开始先认为不需要播放大飞机飞行的音效
            play_fly_sound = 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:
                            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 and each.rect.top < bg_size[1]:
                        play_fly_sound = True

                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:
                            score += 10
                            each.reset()

            # 决定是否播放大飞机飞行音效
            if play_fly_sound:
                enemy3_fly_sound.play(-1)
                play_fly_sound = False
            else:
                enemy3_fly_sound.stop()

            #绘制中飞机
            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 += 6
                            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 += 1
                            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:
                    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 - (i + 1) * life_rect.width - 10, \
                                 height - life_rect.height - 10))

            # 绘制得分
            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))

            # 绘制结束界面
            score_font = pygame.font.Font('font/font.ttf', 40)
            gameover_font = pygame.font.Font('font/font.ttf', 40)
            again_image = pygame.image.load('images/again.png').convert_alpha()
            gameover_image = pygame.image.load(
                'images/gameover.png').convert_alpha()

            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 // 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 = again_image.get_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 = gameover_image.get_rect()
            gameover_rect.left, gameover_rect.top = \
                                (width - gameover_rect.width) // 2, \
                                again_rect.bottom + 50
            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(pause_image, pause_rect)

        if not delay % 5:
            switch = not switch

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Beispiel #30
0
def main():
    pygame.mixer.music.play(-1)
    clock = pygame.time.Clock()
    e1_destory_index = 0
    e2_destory_index = 0
    e3_destory_index = 0
    me_destory_index = 0
    delay = 100
    running = True
    me = myplane.Myplane(bg_size)

    #游戏暂停
    paused = False
    paused_nor_image = pygame.image.load("image/paused_nor.png")
    paused_pressed_image = pygame.image.load("image/paused_pressed.png")
    resume_nor_image = pygame.image.load("image/resume_nor.png")
    resume_pressed_image = pygame.image.load("image/resume_pressed.png")
    paused_rect = paused_nor_image.get_rect()
    paused_rect.left, paused_rect.top = bg_size[0] - paused_rect.width - 10, 10
    #默认显示这个
    paused_image = paused_nor_image
    #分数字体
    score = 0
    score_font = pygame.font.Font("font/font.TTF", 36)

    enemies = pygame.sprite.Group()
    #生成敌方小型飞机
    small_enemies = pygame.sprite.Group()
    add_small_enemies(small_enemies, enemies, 20)
    #生成敌方中型飞机
    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.midtop))
    #用于阻止重复打开记录文件
    recorded = False
    game_over_font = pygame.font.Font("font/font.TTF", 48)
    again_image = pygame.image.load("image/again.png").convert_alpha()
    again_rect = again_image.get_rect()
    gameover_image = pygame.image.load("image/gameover.png").convert_alpha()
    gameover_rect = gameover_image.get_rect()

    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
            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

        if not paused:
            screen.blit(background, (0, 0))
            #绘制得分
            #大,中,小 飞机毁灭时分别得到 10000,6000,1000 分
            score_text = score_font.render("Score:%s" % str(score), True,
                                           WHITE)
            screen.blit(score_text, (10, 5))
            if not (delay % 10):
                bullet1[bullet1_index].reset(me.rect.midtop)
                bullet1_index = (bullet1_index + 1) % BULLET1_NUM
            #检测用户键盘的操作
            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()
            #绘制我方飞机#screen.blit(me.image, me.rect)
            if me.active:
                screen.blit(me.image, me.rect)
            else:
                #毁灭
                me_down_sound.play()
                if not (delay % 3):
                    screen.blit(me.destory_images[me_destory_index], me.rect)
                    me_destory_index = (me_destory_index + 1) % 4
                    if me_destory_index == 0:
                        print("GAME OVER!")  # # # # # # ###
                        running = False  ##################################################################
            #绘制子弹                                                               # # # # # # ###
            for b in bullet1:
                if b.active:
                    b.move()
                    screen.blit(b.image, b.rect)
                    enemy_hit = pygame.sprite.spritecollide(
                        b, enemies, False, pygame.sprite.collide_mask)
                    #if b.rect.top < 0:
                    #     b.reset(me.rect.midtop)
                    if enemy_hit:
                        b.active = False
                        for e in enemy_hit:
                            if e in mid_enemies or e in big_enemies:
                                e.energy -= 1
                                if e.energy == 0:
                                    e.active = False
                            else:
                                e.active = False
                                score += 1000  #################################################################################
            #绘制小型敌机
            for each in small_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                else:
                    #毁灭
                    if not (delay % 3):
                        if e1_destory_index == 1:
                            enemy1_down_sound.play()
                    #       print("e1down",each.rect)
                        screen.blit(each.destory_images[e1_destory_index],
                                    each.rect)
                        e1_destory_index = (e1_destory_index + 1) % 4
                        if e1_destory_index == 1:
                            enemy1_down_sound.stop()
                            #       print("e1stop",each.rect)
                            each.reset()

            #绘制中型飞机
            for each in mid_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                else:
                    #毁灭
                    if not (delay % 3):
                        if e2_destory_index == 0:
                            enemy2_down_sound.play()
                        screen.blit(each.destory_images[e1_destory_index],
                                    each.rect)
                        e2_destory_index = (e1_destory_index + 1) % 4
                        if e2_destory_index == 0:
                            enemy2_down_sound.stop()
                            each.reset()
                            score += 6000
                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)
            #绘制大型飞机
            for each in big_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                    #即将出现在画面中,播放音效
                    if each.rect.bottom >= -50:
                        enemy3_fly_sound.play(-1)
                else:
                    #毁灭
                    if not (delay % 3):
                        if e3_destory_index == 0:
                            enemy3_down_sound.play()
                        screen.blit(each.destory_images[e3_destory_index],
                                    each.rect)
                        e3_destory_index = (e3_destory_index + 1) % 6
                        if e3_destory_index == 0:
                            enemy3_down_sound.stop()
                            each.reset()
                            score += 10000
                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)

            #检测我方飞机是否被碰撞
            enemies_down = pygame.sprite.spritecollide(
                me, enemies, False, pygame.sprite.collide_mask)
            if enemies_down:
                me.active = False
                for e in enemies_down:
                    e.active = False
        #绘制暂停图标
        screen.blit(paused_image, paused_rect)
        #screen.blit(background,(0,0))
        if not running:
            #背景音乐停止
            pygame.mixer.music.stop()
            #停止全部音效
            pygame.mixer.stop()
            if not recorded:
                recorded = True
                #读取历史最高分
                with open("record/recorded.txt", 'r') as f:
                    record_score = int(f.read())
                #如果分数超记录则覆盖录入最高分数
                if score > record_score:
                    with open("record/recorded.txt", 'w') as f:
                        f.write(str(score))
            #绘制结束画面
            record_score_text = score_font.render("Best: %d" % record_score,
                                                  True, (255, 255, 255))
            screen.blit(background, (0, 0))
            screen.blit(record_score_text, (50, 50))
            gameover_text1 = game_over_font.render("Your Score", True,
                                                   (255, 255, 255))
            gameover_text1_rect = gameover_text1.get_rect()
            gameover_text1_rect.left, gameover_text1_rect.top = (
                bg_size[0] - gameover_text1_rect.width) // 2, bg_size[1] // 3
            screen.blit(gameover_text1, gameover_text1_rect)
            gameover_text2 = game_over_font.render(str(score), True,
                                                   (255, 255, 255))
            gameover_text2_rect = gameover_text2.get_rect()
            gameover_text2_rect.left, gameover_text2_rect.top = (
                bg_size[0] - gameover_text2_rect.width
            ) // 2, gameover_text1_rect.bottom + 10
            screen.blit(gameover_text2, gameover_text2_rect)
            again_rect.left, again_rect.top = (
                bg_size[0] -
                again_rect.width) // 2, gameover_text2_rect.bottom + 50
            screen.blit(again_image, again_rect)
            gameover_rect.left, gameover_rect.top = (
                bg_size[0] - gameover_rect.width) // 2, again_rect.bottom + 10
            screen.blit(gameover_image, gameover_rect)
            pygame.display.flip()
            while True:
                #检测用户鼠标操作
                #如果按下鼠标左键
                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()

        pygame.display.flip()
        delay += 1

        clock.tick(60)