Пример #1
0
def main():
    pygame.mixer.music.play(-1)
    me = myplane.MyPlane(bg_size)  # 生成我方飞机
    running = True
    switch_image = False
    delay = 60  # 延时60帧

    # ====================实例化敌方飞机====================
    enemies = pygame.sprite.Group()  # 生成敌方飞机组
    small_enemies = pygame.sprite.Group()  # 敌方小型飞机组
    add_small_enemies(small_enemies, enemies, 1)  # 生成若干敌方小型飞机

    while running:
        clock = pygame.time.Clock()  # 设置帧率
        clock.tick(60)  # 设置帧数为60
        switch_image = not switch_image
        screen.blit(background, (0, 0))

        if delay == 0:
            delay = 60
        delay -= 1

        if not delay % 3:
            switch_image = not switch_image

        if switch_image:
            screen.blit(me.image1, me.rect)
        else:
            screen.blit(me.image2, me.rect)

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

        for each in small_enemies:  # 绘制小型敌机并自动移动
            each.move()
            screen.blit(each.image, each.rect)

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        pygame.display.flip()
Пример #2
0
def main():
    # =============Set background image==============
    background = pygame.image.load("image/background.png")  # Load background image
    gameover_image = pygame.image.load("image/game_over.png")  # game over background image
    gameover_rect = gameover_image.get_rect()
    game_over = False
    restart_button_normal = pygame.image.load("image/restart.png")
    restart_button_hover = pygame.image.load("image/restart_hover.png")
    restart_button_rect = restart_button_normal.get_rect()
    restart_button_rect.left, restart_button_rect.top = (170, 500)

    x = 0  # Set the initial background position
    y = 0
    x1 = 0
    y1 = -HEIGHT

    # ==============Create enemy plane instances==============
    enemies = pygame.sprite.Group()  # Creating all enemy plane groups
    small_enemies = pygame.sprite.Group()  # Creating small enemy plane group
    add_small_enemies(small_enemies, enemies, 1)
    mid_enemies = pygame.sprite.Group()  # Create middle enemy plane group
    add_mid_enemies(mid_enemies, enemies, 1)
    big_enemies = pygame.sprite.Group()  # Create big enemy plane group
    add_big_enemies(big_enemies, enemies, 1)
    small_enemies2 = pygame.sprite.Group()  # Creating small enemy plane group
    add_small_enemies2(small_enemies2, enemies, 1)
    supplies = pygame.sprite.Group()

    # ==============Initializing my plane==============
    me = myplane.MyPlane(bg_size)

    # ===============user score=================
    score = 0
    score_font = pygame.font.SysFont("Chalkboard", 24)
    game_over_player_score_font = pygame.font.SysFont("Chalkboard", 48)
    high_score_font = pygame.font.SysFont("Chalkboard", 36)

    # =========== current game difficulty level ===========
    level = 1

    # ===============Create all the bullets=================
    enemy_bullets = pygame.sprite.Group()

    my_bullets = []  # Generate my bullets
    my_bullet_index = 0
    my_bullet_num = 300  # Amount of bullet instances
    for i in range(my_bullet_num):
        b = bullet.MyBullet()
        my_bullets.append(b)

    enemy_bullets1 = []  # Generate enemy bullets of middle enemy
    enemy_bullet1_index = 0
    enemy_bullet1_num = 300
    for i in range(enemy_bullet1_num):
        b = bullet.EnemyBullet1()
        enemy_bullets1.append(b)
        enemy_bullets.add(b)

    enemy_bullets2 = []  # Generate enemy bullets of big enemy
    enemy_bullet2_index = 0
    enemy_bullet3_num = 300
    for i in range(enemy_bullet3_num):
        b = bullet.EnemyBullet2()
        enemy_bullets2.append(b)
        enemy_bullets.add(b)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                exit()

        # =================Control the plane=================
        control_plane_x = 0
        control_plane_y = 0
        if me.active:
            key_pressed = pygame.key.get_pressed()  # Get user input sequence
            if key_pressed[K_w] or key_pressed[K_UP]:
                control_plane_y = 1
            if key_pressed[K_s] or key_pressed[K_DOWN]:
                control_plane_y = -1
            if key_pressed[K_a] or key_pressed[K_LEFT]:
                control_plane_x = -1
            if key_pressed[K_d] or key_pressed[K_RIGHT]:
                control_plane_x = 1
            movement_angle = atan2(control_plane_y, control_plane_x)
            if control_plane_x == 0 and control_plane_y == 0:
                me.move(movement_angle, False)
            else:
                me.move(movement_angle, True)

            # ==============Game difficulty level================
            critical_score = 3000 * 3 ** (level - 1)
            if score >= critical_score:
                level += 1
                level_up_sound.play()
                add_small_enemies(small_enemies, enemies, 3)
                add_small_enemies2(small_enemies2, enemies, 2)
                add_mid_enemies(mid_enemies, enemies, 2)
                add_big_enemies(big_enemies, enemies, 1)
                for i in enemy.Enemy.__subclasses__():
                    i.upgraded_energy *= 1.2 ** (level - 1)
                enemy.MidEnemy.upgraded_shooting_interval = int(
                    i.upgraded_shooting_interval * ((4 / 5) ** (level - 1)) + 1)
                enemy.BigEnemy.upgraded_shooting_interval = int(
                    i.upgraded_shooting_interval * ((4 / 5) ** (level - 1)) + 1)

        # ============Set the background to scroll (repetitively blit same two images)========
        screen.blit(background, (x, y))
        screen.blit(background, (x1, y1))
        y1 += 3
        y += 3
        if y > HEIGHT:
            y = -HEIGHT
        if y1 > HEIGHT:
            y1 = -HEIGHT

        # =========Shooting bullets according to different bullet levels of my plane==========
        me.shooting_time_index += 1  # Shooting time index of my plane increase by 1 in every frame

        if me.active:
            if me.bullet_level <= 3:
                if me.bullet_level == 1:
                    bullet.MyBullet.shooting_interval = 20
                elif me.bullet_level == 2:
                    bullet.MyBullet.shooting_interval = 15
                elif me.bullet_level == 3:
                    bullet.MyBullet.shooting_interval = 11
                if me.shooting_time_index % bullet.MyBullet.shooting_interval == 0:  # Shoot a bullet at a certain interval
                    bullet_sound.play()
                    my_bullets[my_bullet_index].shoot(me.rect.midtop)
                    my_bullet_index = (my_bullet_index + 1) % my_bullet_num
            elif 4 <= me.bullet_level <= 6:
                if me.bullet_level == 4:
                    bullet.MyBullet.shooting_interval = 17
                elif me.bullet_level == 5:
                    bullet.MyBullet.shooting_interval = 12
                elif me.bullet_level == 6:
                    bullet.MyBullet.shooting_interval = 8
                if me.shooting_time_index % bullet.MyBullet.shooting_interval == 0:
                    bullet_sound.play()
                    my_bullets[my_bullet_index].shoot((me.rect.centerx - 28, me.rect.centery))
                    my_bullets[my_bullet_index + 1].shoot((me.rect.centerx + 23, me.rect.centery))
                    my_bullet_index = (my_bullet_index + 2) % my_bullet_num
                    if my_bullet_index >= my_bullet_num - 1:
                        my_bullet_index = 0

            elif 7 <= me.bullet_level <= 9:
                if me.bullet_level == 7:
                    bullet.MyBullet.shooting_interval = 9
                elif me.bullet_level == 8:
                    bullet.MyBullet.shooting_interval = 7
                elif me.bullet_level == 9:
                    bullet.MyBullet.shooting_interval = 4
                if me.shooting_time_index % bullet.MyBullet.shooting_interval == 0:
                    bullet_sound.play()
                    my_bullets[my_bullet_index].shoot((me.rect.centerx - 28, me.rect.centery), 105)
                    my_bullets[my_bullet_index + 1].shoot((me.rect.centerx - 4, me.rect.centery), 90)
                    my_bullets[my_bullet_index + 2].shoot((me.rect.centerx + 23, me.rect.centery), 75)
                    my_bullet_index = (my_bullet_index + 3) % my_bullet_num
                    if my_bullet_index >= my_bullet_num - 2:
                        my_bullet_index = 0

            elif me.bullet_level == 10:
                bullet.MyBullet.shooting_interval = 4
                if me.shooting_time_index % bullet.MyBullet.shooting_interval == 0:
                    bullet_sound.play()
                    my_bullets[my_bullet_index].shoot((me.rect.centerx - 25, me.rect.centery), 120)
                    my_bullets[my_bullet_index + 1].shoot((me.rect.centerx - 4, me.rect.centery), 90)
                    my_bullets[my_bullet_index + 2].shoot((me.rect.centerx + 17, me.rect.centery), 60)
                    my_bullets[my_bullet_index + 3].shoot((me.rect.centerx + 14, me.rect.centery), 75)
                    my_bullets[my_bullet_index + 4].shoot((me.rect.centerx - 22, me.rect.centery), 105)
                    my_bullet_index = (my_bullet_index + 5) % my_bullet_num
                    if my_bullet_index >= my_bullet_num - 4:
                        my_bullet_index = 0

        # ================The move of my bullets===========
        if me.active:
            for b in my_bullets:
                if b.active:
                    if me.bullet_level == 1 or me.bullet_level == 4 or me.bullet_level == 7:
                        b.move()
                        bullet_image = b.image1
                    elif me.bullet_level == 2 or me.bullet_level == 5 or me.bullet_level == 8:
                        b.move()
                        bullet_image = b.image2
                    elif me.bullet_level == 3 or me.bullet_level == 6 or me.bullet_level == 9 or me.bullet_level == 10:
                        b.move()
                        bullet_image = b.image3
                    screen.blit(bullet_image, b.rect)

        # ================Collision between the bullets and enemy planes============
        for b in my_bullets:
            if b.active:
                enemies_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask)
                if enemies_hit:
                    b.active = False
                    for e in enemies_hit:
                        e.energy -= 1
                        e.hit = True  # Plane is hit
                        if e.energy <= 0:
                            e.active = False


        # =====Detect whether the plane touches the supply======
        if me.active:
            supplies_got = pygame.sprite.spritecollide(me, supplies, True, pygame.sprite.collide_mask)
            for s in supplies_got:
                if s.show:
                    get_bomb_sound.play()

                    # ================Bullet Supply==============
                    if isinstance(s, supply.BulletSupply):
                        me.bullet_level += 1
                        if me.bullet_level >= 10:
                            me.bullet_level = 10
                    elif isinstance(s, supply.LifeSupply):
                        me.life += 30
                        if me.life >= 100:
                            me.life = 100
                    elif isinstance(s, supply.Shield):
                        me.invincible = True
                        invincible_count_down = frame_rate * 10
                        shield = myplane.Shield(me.rect.center)
                    s.show = False

        # ============The movement of the shield===========
        if me.invincible:
            shield.rect.center = me.rect.center

        #============Invincible time counting down============
        if me.invincible:
            invincible_count_down -= 1
            if invincible_count_down == 0:
                me.invincible = False

        # =====Detect whether there is a collision between the shield and enemy planes and bullets======
        if me.invincible:
            enemies_hit_by_shield = pygame.sprite.spritecollide(shield, enemies, False, pygame.sprite.collide_mask)
            bullets_on_shield = pygame.sprite.spritecollide(shield, enemy_bullets, False,
                                                      pygame.sprite.collide_mask)
            if enemies_hit_by_shield:
                for e in enemies_hit_by_shield:
                    if e.active:
                        e.active = False
            if bullets_on_shield:
                for b in bullets_on_shield:
                    b.active = False

        # =====Detect whether there is a collision between my plane and enemy planes======
        if me.active:
            enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask)
            if enemies_down:  # If the list of collision detection is not empty, then collision happens.
                for e in enemies_down:
                    if e.active:
                        me.life -= e.crashing_power
                        e.active = False  # Enemy plane destroyed

        # =========Detect whether my plane touches enemy_bullets===========
        if me.active:
            bullets_hit = pygame.sprite.spritecollide(me, enemy_bullets, False,
                                                      pygame.sprite.collide_mask)
            for b in bullets_hit:
                if b.active:
                    me.hit = True
                    me.life -= b.power
                    b.active = False

        # =========Blit the big enemies and have them move==========
        for each in big_enemies:
            if each.active:
                each.move()
                each.shooting_time_index += 1
                screen.blit(animation_frame("big_enemy_{}".format(id(each)), each.images, 3), each.rect)
                if each.shooting_time_index % each.shooting_interval == 0:  # Shoot a bullet at a certain interval
                    bullet3_angle = (180 / pi) * atan2((each.rect.centery - me.rect.centery),
                                                       (me.rect.centerx - each.rect.centerx))
                    enemy_bullets2[enemy_bullet2_index].shoot((each.rect.centerx - 10, each.rect.centery),
                                                              bullet3_angle)  # Big enemy shooting bullets
                    enemy_bullet2_index = (enemy_bullet2_index + 1) % enemy_bullet3_num

        # =========Blit the mid enemies and have them move==========
        for each in mid_enemies:
            if each.active:
                each.move()
                each.shooting_time_index += 1
                screen.blit(each.image, each.rect)
                if each.shooting_time_index % each.shooting_interval == 0:  # Shoot a bullet at a certain interval
                    enemy_bullets1[enemy_bullet1_index].shoot((each.rect.centerx - 3, each.rect.centery),
                                                              -90)  # Shooting bullets by middle enemy
                    enemy_bullet1_index = (enemy_bullet1_index + 1) % enemy_bullet1_num

        # =========Blit the small enemies and have them move==========
        for each in small_enemies:
            if each.active:
                each.move()
                screen.blit(each.image, each.rect)

        # =========Blit the small enemies2 and have them move==========
        for each in small_enemies2:
            if each.active:
                if each.init_position_left < 0:
                    each.move(-60)
                else:
                    each.move(-120)
                screen.blit(each.image, each.rect)

        # =========When the big enemy is hit==============
        for each in big_enemies:
            if each.active:
                if each.hit:
                    screen.blit(each.image_hit, each.rect)
                    each.hit = False

        # =========When the middle enemy is hit==============
        for each in mid_enemies:
            if each.active:
                if each.hit:
                    screen.blit(each.image_hit, each.rect)
                    each.hit = False

        # =========When enemy is destroyed===========
        for each in enemies:
            destroy_sound = globals()["{}_destroy_sound".format(each.__class__.__name__)]
            destroy_frame_len = len(each.destroy_images)
            if not each.active:
                destroy_sound.play()
                screen.blit(animation_frame("enemy_{}".format(id(each)),
                                            each.destroy_images,
                                            destroy_frame_len),
                            each.rect)
                if all_animation.get("enemy_{}".format(id(each))).is_finished:
                    score += each.destroy_score
                    if getattr(each, "supply", False):
                        each.supply.drop(((each.rect.centerx - each.supply.rect.width / 2),
                                          each.rect.centery))  # Dropping supplies when destroyed
                        supplies.add(each.supply)
                    each.reset()

        # ================The move of the bullets from big enemy===========-
        for b in enemy_bullets2:
            if b.active:
                b.move()
                screen.blit(b.image, b.rect)

        # ================The move of the bullets from middle enemy===========-
        for b in enemy_bullets1:
            if b.active:
                b.move()
                screen.blit(b.image, b.rect)

        # =============The move of the supplies===============
        for each in supplies:
            if each.show:
                each.move(bg_size)
                screen.blit(each.image, each.rect)

        # ========Draw the plane and switch between two images to realize the air-jetting effect======
        if me.active:
            screen.blit(animation_frame("me", me.images, 3), me.rect)  # Change the image every 3 frames

        # =============When my plane is hit=============
        if me.active:
            if me.hit:
                screen.blit(animation_frame("me_hit", me.images_hit, 1), me.rect)
                if all_animation.get("me_hit").is_finished:
                    me.hit = False


        # =============Display the user score====================
        score_text = score_font.render("Score: {}".format(str(score)), True, BLACK)
        screen.blit(score_text, (10, 40))

        # =============Draw the remaining blood of my plane================
        pygame.draw.line(screen, (75, 75, 75), (10, 20), (200, 20), 30)
        if me.life / 100 > 0.3:
            energy_color = GREEN
        elif 0.15 <= me.life / 100 <= 0.3:
            energy_color = YELLOW
        elif 0 <= me.life / 100 < 0.15:
            energy_color = RED
        pygame.draw.line(screen, energy_color, (10, 20), ((me.life / 100) * 190 + 11, 20), 30)

        # ===============If my plane is invincible, blit the shield and life bar===============
        if me.invincible:
            screen.blit(shield.image, shield.rect)
            pygame.draw.line(screen, (217,255,200), (10, 20), ((me.life / 100) * 190 + 11, 20), 30)
            invincible_text = score_font.render("INVINCIBLE", True, (0,155,0))

            # ============The blink of the shield within the last 3 seconds========
            if invincible_count_down<= frame_rate * 2:
                if invincible_count_down % 3:
                    invincible_text = score_font.render("", True, (0,155,0))
            screen.blit(invincible_text, (40, 7))


        # =============Detect whether my plane is destroyed==============
        if game_over == False:
            if me.life <= 0:
                me.life = 0
                me.active = False
                # When my plane is destroyed, create the animation
                screen.blit(animation_frame("me_destroy", me.destroy_images, 5), me.rect)

        # =============Show the game over screen============
        if me.active == False:
            if all_animation.get("me_destroy").is_finished:
                game_over = True

        # =============When game over==============
        if game_over:  # Detect the restart button
            restart_button = restart_button_normal
            if restart_button_rect.collidepoint(pygame.mouse.get_pos()):
                restart_button = restart_button_hover
                for event in pygame.event.get():
                    if event.type == MOUSEBUTTONDOWN:
                        game_over = False
                        pygame.mixer.music.play(-1)
                        main()

            with open("high_score.txt", "r") as f:  # Load the high score data from txt file
                high_score = int(f.read())
            if score > high_score:  # If player's scoring is higher, then save it
                with open("high_score.txt", "w") as f:
                    f.write(str(score))
            player_score_text = game_over_player_score_font.render("{}".format(score), True, WHITE)
            high_score_text = high_score_font.render("{}".format(high_score), True, WHITE)
            screen.blit(gameover_image, gameover_rect)  # Show game over screen
            screen.blit(player_score_text, (230, 210))
            screen.blit(high_score_text, (230, 390))
            screen.blit(restart_button, restart_button_rect)
            pygame.mixer.music.stop()  # Stop the background music

        pygame.display.flip()
        clock.tick(frame_rate)  # Set the frame rate to 60
Пример #3
0
def main():
    """
    4.1 -Play the bg music
    """
    pygame.mixer.music.play(-1, 0.0)
    
    """
    4.2 -Draw myplane
    """
    me = myplane.MyPlane(bg_size)

    """
    4.3 -Draw the enemies
    """
    enemies = pygame.sprite.Group()

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

    # Draw midiume enemies
    mid_enemies = pygame.sprite.Group()
    add_mid_enemies(mid_enemies, enemies, 4)

    # Draw big enemies
    big_enemies = pygame.sprite.Group()
    add_big_enemies(big_enemies, enemies, 2)

    # Load boss event but not draw it
    boss = pygame.sprite.Group()


    """
    4.4 -Draw bullet and bomb
    """
    # Draw normal bullet
    bullet1 = []
    bullet1_index = 0
    BULLET1_NUM = 4
    for i in range(BULLET1_NUM):
        bullet1.append(bullet.Bullet1(me.rect.midtop))

    # Draw super bullet
    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)))

    # Bomb
    bomb_image = pygame.image.load("images/bomb.png").convert_alpha()
    bomb_rect = bomb_image.get_rect()
    bomb_font = pygame.font.SysFont("arial", 48)
    bomb_num = 3


    """
    4.5 -Set the basical parameters
    """
    clock = pygame.time.Clock()

    # Hit effective images index
    e1_destroy_index = 0
    e2_destroy_index = 0
    e3_destroy_index = 0
    boss_destory_index = 0
    me_destroy_index = 0

    # Score
    score = 0
    scoredelta = 0
    score_font = pygame.font.Font("font/font.ttf", 36)

    # Game Pause/Resume button
    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

    # Set the difficult level
    level = 1

    # Supply package send every 15sec
    bullet_supply = supply.Bullet_Supply(bg_size)
    bomb_supply = supply.Bomb_Supply(bg_size)
    life_supply = supply.Life_Supply(bg_size)
    SUPPLY_TIME = USEREVENT
    pygame.time.set_timer(SUPPLY_TIME, 15 * 1000)

    # Superbullet timer
    DOUBLE_BULLET_TIME = USEREVENT + 1

    # Superbullet marker
    is_double_bullet = False

    # Invincible timer
    INVINCIBLE_TIME = USEREVENT + 2

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

    # Recorder file opening marker
    recorded = False

    # Game over
    gameover_font = pygame.font.SysFont("arial", 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
    switch_image = True

    # Delay
    delay = 100

    running = True
    boss_live = False
    
    #Main Loop
    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, 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 = 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()
                supply_type = choice([0,1,2])
                if  supply_type == 1:
                    bomb_supply.reset()
                elif supply_type == 2:
                    life_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)
                         

        """
        Diffcult level judgment
        ------------------------------------------------------
        """
        #the following-line code for test the boss
        if level >3 and scoredelta > 100000 and score > 500000 and boss_live == False:
        #if score > 1000 and scoredelta > 6000 and boss_live == False:
            upgrade_sound.play()
            # Add 1 boss
            add_boss(boss, enemies)
            scoredelta = 0
            boss_live = True
            level -= level
            
        if level == 1 and score > 100000:
            level = 2
            upgrade_sound.play()
            
            # Add 3 small, 2 mid, 1 big
            add_small_enemies(small_enemies, enemies, 3)
            add_mid_enemies(mid_enemies, enemies, 2)
            add_big_enemies(big_enemies, enemies, 1)
            
            # small speed up
            inc_speed(small_enemies, 1)
        elif level == 2 and score > 200000:
            level = 3
            upgrade_sound.play()
            # Add 5 small, 3 mid, 2 big
            add_small_enemies(small_enemies, enemies, 5)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_big_enemies(big_enemies, enemies, 2)
            
            # small speed up
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)
        elif level == 3 and score > 300000:
            level = 4
            upgrade_sound.play()
            # Add 5 small, 3 mid, 2 big
            add_small_enemies(small_enemies, enemies, 5)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_big_enemies(big_enemies, enemies, 2)
            
            # small speed up
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)
        elif level == 4 and score > 400000:
            level = 5
            upgrade_sound.play()
            # Add 5 small, 3 mid, 2 big
            add_small_enemies(small_enemies, enemies, 5)
            add_mid_enemies(mid_enemies, enemies, 3)
            add_big_enemies(big_enemies, enemies, 2)
            
            # small speed up
            inc_speed(small_enemies, 1)
            inc_speed(mid_enemies, 1)
             
        screen.blit(background, (0, 0))
                
        if life_num > -1 and not paused:
            # keyevent check
            key_pressed = pygame.key.get_pressed()

            if key_pressed[K_w] or key_pressed[K_UP]:
                me.moveUp()
            if key_pressed[K_s] or key_pressed[K_DOWN]:
                me.moveDown()
            if key_pressed[K_a] or key_pressed[K_LEFT]:
                me.moveLeft()
            if key_pressed[K_d] or key_pressed[K_RIGHT]:
                me.moveRight()

            # Draw bomb and check the supply getting
            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
            
            # Draw life supply and check the supply getting
            if life_supply.active:
                life_supply.move()
                screen.blit(life_supply.image, life_supply.rect)
                if pygame.sprite.collide_mask(life_supply, me):
                    get_life_sound.play()
                    if life_num < 5:
                        life_num += 1
                    life_supply.active = False

            # Draw superbullet and check the supply getting
            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

            # launch bullet
            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

                
            # enemy hit check
            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 or e in boss:
                                e.hit = True
                                e.energy -= 1
                                if e.energy == 0:
                                    e.active = False
                            else:
                                e.active = False
            
            # Draw boss
            for each in boss:
                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)

                    # Draw healthvalue
                    pygame.draw.line(screen, BLACK, \
                                     (each.rect.left, each.rect.top + 5), \
                                     (each.rect.right, each.rect.top + 5), \
                                     3)
                    # health value >20% green else red
                    energy_remain = float(each.energy / enemy.Boss.energy)
                    if energy_remain > 0.2:
                        energy_color = GREEN
                    else:
                        energy_color = RED
                    pygame.draw.line(screen, energy_color, \
                                     (each.rect.left, each.rect.top - 5), \
                                     (each.rect.left + int(each.rect.width * energy_remain), \
                                      each.rect.top - 5), 2)
                        
                    # play music
                    if each.rect.bottom == -50:
                        enemy3_fly_sound.play(-1)
                else:
                    # enemy down
                    if not(delay * 10 % 3):
                        if boss_destory_index == 0:
                            enemy3_down_sound.play()
                        screen.blit(each.destroy_images[boss_destory_index], each.rect)
                        boss_destory_index = (boss_destory_index + 1) % 6
                        if boss_destory_index == 0:
                            enemy3_fly_sound.stop()
                            score += 50000
                            scoredelta += 50000
                            boss_live = False
                            each.reset()
                        
            
            
            # Draw big enemy
            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)

                    # Draw healthvalue
                    pygame.draw.line(screen, BLACK, \
                                     (each.rect.left, each.rect.top - 5), \
                                     (each.rect.right, each.rect.top - 5), \
                                     3)
                    # health value >20% green else red
                    energy_remain = float(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 + int(each.rect.width * energy_remain), \
                                      each.rect.top - 5), 2)
                        
                    # play music
                    if each.rect.bottom == -50:
                        enemy3_fly_sound.play(-1)
                else:
                    # enemy down
                    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
                            scoredelta += 10000
                            each.reset()

            # Draw middle enemy
            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)

                    # Draw healthvalue
                    pygame.draw.line(screen, BLACK, \
                                     (each.rect.left, each.rect.top - 5), \
                                     (each.rect.right, each.rect.top - 5), \
                                     3)
                    # health value >20% green else red
                    energy_remain = float(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 + int(each.rect.width * energy_remain), \
                                      each.rect.top - 5), 2)
                else:
                    # enemy down
                    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
                            scoredelta += 6000
                            each.reset()

            # Draw small enemy
            for each in small_enemies:
                if each.active:
                    each.move()
                    screen.blit(each.image, each.rect)
                else:
                    # enemy down
                    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
                            scoredelta += 1000
                            each.reset()

            # Check my collision
            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
            
            # Draw my plane
            if me.active:
                if switch_image:
                    screen.blit(me.image1, me.rect)
                else:
                    screen.blit(me.image2, me.rect)
            else:
                # my plane down
                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)

            # Draw bomb number
            if bomb_num < 5:
                bomb_text = bomb_font.render("* %d" % bomb_num, True, LIGHTGREEN)
            else:
                bomb_text = bomb_font.render("MAX", True,LIGHTGREEN)
            text_rect = bomb_text.get_rect()
            screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))
            screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height))

            # Draw remaining life number
            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))

            # Draw sorce
            score_text = score_font.render("Score : %s" % str(score), True, LIGHTGREEN)
            screen.blit(score_text, (10, 5))

        # Draw gameover
        elif life_num == -1:
            #Stop bgmusic
            pygame.mixer.music.stop()

            # Stop sound effct
            pygame.mixer.stop()

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

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

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

            # Draw gameover screen
            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)

            # Mouse motion check
            # Mouse left button down
            if pygame.mouse.get_pressed()[0]:
                # get mouse position
                pos = pygame.mouse.get_pos()
                # restart
                if again_rect.left < pos[0] < again_rect.right and \
                   again_rect.top < pos[1] < again_rect.bottom:
                    # recall main function
                    main()
                # end the game          
                elif gameover_rect.left < pos[0] < gameover_rect.right and \
                     gameover_rect.top < pos[1] < gameover_rect.bottom:
                    # exit
                    pygame.quit()
                    sys.exit()      

        # Draw pause button
        screen.blit(paused_image, paused_rect)

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

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Пример #4
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)

    clock = pygame.time.Clock()
    #用于切换图片
    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))
        #绘制敌方大型飞机
        for each in big_enemies:
            each.move()
            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()
        # 绘制敌方中型飞机
        for each in mid_enemies:
            each.move()
            screen.blit(each.image, each.rect)
        # 绘制敌方中型飞机
        for each in small_enemies:
            each.move()
            screen.blit(each.image, each.rect)

        #绘制我的飞机

        if switch_image:
            screen.blit(me.image1, me.rect)
        else:
            screen.blit(me.image2, me.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)
Пример #5
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
Пример #6
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
Пример #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

    # 用于切换图片
    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)
Пример #8
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)
Пример #9
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)
Пример #10
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)
Пример #11
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)
Пример #12
0
def main():

    pygame.mixer.music.play(-1)

    me = myplane.MyPlane(bg_size)

    enemies = pygame.sprite.Group()

    # Initialize small enemies
    small_enemies = pygame.sprite.Group()
    add_small_enemies(small_enemies, enemies, 50)

    # Initialize mid enemies
    mid_enemies = pygame.sprite.Group()
    add_mid_enemies(mid_enemies, enemies, 15)

    # Initialize big enemies
    big_enemies = pygame.sprite.Group()
    add_big_enemies(big_enemies, enemies, 6)

    clock = pygame.time.Clock()

    # Control the aircraft destroy effect
    small_destroy_index = 0
    mid_destroy_index = 0
    big_destroy_index = 0
    me_destroy_index = 0

    # Control the dynamic effect of images
    switch_image = True
    delay = 100

    # You have three life points
    life = 3
    life_image = pygame.image.load('image/lifejet.png').convert_alpha()
    life_rect = life_image.get_rect()

    # Initialize score
    score = 0
    score_font = pygame.font.Font('SentyCreamPuff.ttf', 36)
    final_score_font = pygame.font.Font('SentyCreamPuff.ttf', 48)

    # Pause button stuff
    paused = False
    pause_regular_image = pygame.image.load(
        'image/game_pause_nor.png').convert_alpha()
    pause_pressed_image = pygame.image.load(
        'image/game_pause_pressed.png').convert_alpha()
    resume_regular_image = pygame.image.load(
        'image/game_resume_nor.png').convert_alpha()
    resume_pressed_image = pygame.image.load(
        'image/game_resume_pressed.png').convert_alpha()
    pause_rect = pause_regular_image.get_rect()
    pause_rect.left, pause_rect.top = width - pause_rect.width - 5, 5
    pause_image = pause_regular_image

    pause_animation1 = pygame.image.load(
        'image/game_loading1.png').convert_alpha()
    pause_animation2 = pygame.image.load(
        'image/game_loading2.png').convert_alpha()
    pause_animation3 = pygame.image.load(
        'image/game_loading3.png').convert_alpha()

    # Game difficulty level
    level = 1

    # Full Screen bomb!
    bomb_image = pygame.image.load('image/bomb.png').convert_alpha()
    bomb_rect = bomb_image.get_rect()
    bomb_font = pygame.font.Font('SentyCreamPuff.ttf', 48)
    bomb_num = 0  # Without any bomb at the very beginning

    # Bomb supply + bullet supply
    bomb_supply = supply.BombSupply(bg_size)
    bullet_supply = supply.BulletSupply(bg_size)
    supply_timer = USEREVENT
    pygame.time.set_timer(supply_timer, 30 * 1000)

    # Double bullet timer
    double_bullet_timer = USEREVENT + 1
    is_double_bullets = False

    # Invincible period timer
    invincible_timer = USEREVENT + 2

    # Create regular bullets
    bullets1 = []
    bullet1_index = 0
    bullet_num = 6
    for i in range(bullet_num):
        bullet_position = (me.rect.midtop[0] - 3, me.rect.midtop[1])
        bullets1.append(bullet.Bullet(bullet_position))

    # Create double bulltes
    bullets2 = []
    bullet2_index = 0
    double_num = 8
    for i in range(double_num):
        bullets2.append(
            bullet.DoubleBullet((me.rect.centerx - 35, me.rect.centery)))
        bullets2.append(
            bullet.DoubleBullet((me.rect.centerx + 28, me.rect.centery)))

    # Set bullets to be regular bullets initially
    bullets = bullets1

    # Play again button
    again_image = pygame.image.load('image/again.png').convert_alpha()
    again_rect = again_image.get_rect()
    again_rect.left += 150
    again_rect.top += 450

    terminated = False

    running = True

    while running:

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

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

            # Click to pause the game
            elif event.type == MOUSEBUTTONDOWN:
                if event.button == 1 and life == 0 and again_rect.collidepoint(
                        event.pos):
                    # Restart the game
                    main()
                elif event.button == 1 and pause_rect.collidepoint(event.pos):
                    paused = not paused
                    if paused:
                        pygame.time.set_timer(supply_timer, 0)
                        pygame.mixer.music.pause()
                        pygame.mixer.pause()
                    else:
                        pygame.time.set_timer(supply_timer, 30 * 1000)
                        pygame.mixer.music.unpause()
                        pygame.mixer.unpause()

            # When cursor is moving and interact with the pause button
            elif event.type == MOUSEMOTION:
                if pause_rect.collidepoint(event.pos):
                    if paused:
                        pause_image = resume_pressed_image
                    else:
                        pause_image = pause_pressed_image
                else:
                    if paused:
                        pause_image = resume_regular_image
                    else:
                        pause_image = pause_regular_image

            # Hit space bar and use the full-screen bomb
            elif event.type == KEYDOWN:
                if event.key == K_SPACE:
                    if bomb_num:
                        bomb_num -= 1
                        for e in enemies:
                            if e.rect.bottom > 0:
                                e.alive = False

            # Provide a supply every 30s
            elif event.type == supply_timer:
                if random.random() > 0.5:
                    bullet_supply.reset()
                else:
                    bomb_supply.reset()

            # Double firing period
            elif event.type == double_bullet_timer:
                is_double_bullets = False
                pygame.time.set_timer(double_bullet_timer, 0)

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

        # Delay effect, avoid image switching too fast
        delay -= 1
        if delay == 0:
            delay = 100
        if not (delay % 10):
            switch_image = not switch_image

        # Draw score
        score_text = score_font.render('Score: %s' % str(score), True, black)
        screen.blit(score_text, (5, 5))

        # Draw pause or resume buttion
        screen.blit(pause_image, pause_rect)
        if paused and delay % 33 > 22:
            screen.blit(pause_animation1, (90, 380))
        elif paused and delay % 33 > 11:
            screen.blit(pause_animation2, (140, 380))
        elif paused:
            screen.blit(pause_animation3, (190, 380))

        # Draw bombs
        bomb_text = bomb_font.render('x %d' % bomb_num, True, black)
        text_rect = bomb_text.get_rect()
        screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))
        screen.blit(bomb_text,
                    (20 + bomb_rect.width, height - 5 - text_rect.height))

        # Draw life points
        for i in range(life):
            life_rect.left = width - 50 * (i + 1)
            life_rect.top = height - 70
            screen.blit(life_image, life_rect)

        # Control the game difficulty level
        if level == 1 and score > 2000:
            level = 2
            add_small_enemies(small_enemies, enemies, 10)
            add_mid_enemies(mid_enemies, enemies, 5)
            add_big_enemies(big_enemies, enemies, 2)
            increase_speed(small_enemies, 1)

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

        if level == 3 and score > 10000:
            level = 4
            #add_small_enemies(small_enemies,enemies,10)
            add_mid_enemies(mid_enemies, enemies, 2)
            add_big_enemies(big_enemies, enemies, 1)
            increase_speed(small_enemies, 1)
            increase_speed(mid_enemies, 1)
            increase_speed(big_enemies, 1)

        # Only play when the game is unpaused
        if (not paused) and life:
            # Player's control
            key_pressed = pygame.key.get_pressed()
            if key_pressed[K_w] or key_pressed[K_UP]:
                me.moveUp()
            if key_pressed[K_s] or key_pressed[K_DOWN]:
                me.moveDown()
            if key_pressed[K_a] or key_pressed[K_LEFT]:
                me.moveLeft()
            if key_pressed[K_d] or key_pressed[K_RIGHT]:
                me.moveRight()

            # Draw bomb supply and test whether player gets it
            if bomb_supply.active:
                bomb_supply.move()
                screen.blit(bomb_supply.image, bomb_supply.rect)
                if pygame.sprite.collide_mask(bomb_supply, me):
                    get_bomb_sound.play()
                    if bomb_num < 3:
                        bomb_num += 1
                    bomb_supply.active = False

            # Draw bullet supply and test whether player gets it
            if bullet_supply.active:
                bullet_supply.move()
                screen.blit(bullet_supply.image, bullet_supply.rect)
                if pygame.sprite.collide_mask(bullet_supply, me):
                    get_bullet_sound.play()
                    # Double bullets fire!
                    is_double_bullets = True
                    pygame.time.set_timer(double_bullet_timer, 20 * 1000)
                    bullet_supply.active = False

            # Bullets, both regular and double
            if is_double_bullets and not (delay % 5):
                bullet_sound.play()
                bullets = bullets2
                bullets[bullet2_index].reset(
                    (me.rect.centerx - 35, me.rect.centery))
                bullets[bullet2_index + 1].reset(
                    (me.rect.centerx + 28, me.rect.centery))
                bullet2_index = (bullet2_index + 2) % (double_num * 2)

            elif not is_double_bullets and not (delay % 10):
                bullets = bullets1
                bullet_position = (me.rect.midtop[0] - 3, me.rect.midtop[1])
                bullets[bullet1_index].reset(bullet_position)
                bullet1_index = (bullet1_index + 1) % bullet_num

            # Draw bullet and Collision test (bullet and enemy)
            for b in bullets:
                if b.active:
                    b.move()
                    screen.blit(b.image, b.rect)
                    enemy_hit = pygame.sprite.spritecollide(
                        b, enemies, False, pygame.sprite.collide_mask)
                    if enemy_hit:
                        b.active = False
                        for e in enemy_hit:
                            if e in mid_enemies or e in big_enemies:
                                e.hit = True
                                e.hp -= 1
                                if e.hp == 0:
                                    e.alive = False
                            else:
                                # If hit a small enemy
                                e.alive = False

            # Collision test (jet and enemy)
            crashed = pygame.sprite.spritecollide(me, enemies, False,
                                                  pygame.sprite.collide_mask)
            if crashed and not me.invincible:
                me.alive = False
                for e in crashed:
                    e.alive = False

            # Draw big enemies
            for e in big_enemies:
                if e.alive:
                    e.move()
                    if e.hit:
                        # Show some damage effects
                        screen.blit(e.image_hit, e.rect)
                        e.hit = False
                    else:
                        if switch_image:
                            screen.blit(e.image, e.rect)
                        else:
                            screen.blit(e.image1, e.rect)
                    if e.rect.bottom == -50:
                        enemy3_fly_sound.play(-1)

                    # Draw hp bar
                    pygame.draw.line(screen, black, \
                                     (e.rect.left, e.rect.bottom + 5), \
                                     (e.rect.right, e.rect.bottom +5), 2)
                    hp_percentage = float(e.hp) / enemy.BigEnemy.hp
                    if hp_percentage > 0.3:
                        hp_color = green
                    else:
                        hp_color = red
                    pygame.draw.line(screen, hp_color, \
                                     (e.rect.left, e.rect.bottom + 5), \
                                     (e.rect.left+e.rect.width*hp_percentage, \
                                      e.rect.bottom + 5), 2)

                else:
                    # Enemy blows up!
                    # Use the delay effect to entend the time interval among
                    # blow up images, make the blow animation better
                    screen.blit(e.destroy_images[big_destroy_index], e.rect)
                    if not (delay % 3):
                        # Only play the sound once per explosion
                        if big_destroy_index == 0:
                            enemy3_down_sound.play()
                        # Keep the index value between 0 and 5
                        big_destroy_index = (big_destroy_index + 1) % 6
                        if big_destroy_index == 0:
                            score += 1000
                            enemy3_fly_sound.stop()
                            e.reset()

            # Draw mid enemies
            for e in mid_enemies:
                if e.alive:
                    e.move()
                    if e.hit:
                        # Show some damage effects
                        screen.blit(e.image_hit, e.rect)
                        e.hit = False
                    else:
                        screen.blit(e.image, e.rect)

                    # Draw hp bar
                    pygame.draw.line(screen, black, \
                                     (e.rect.left, e.rect.bottom + 5), \
                                     (e.rect.right, e.rect.bottom +5), 2)
                    hp_percentage = float(e.hp) / enemy.MidEnemy.hp
                    if hp_percentage > 0.3:
                        hp_color = green
                    else:
                        hp_color = red
                    pygame.draw.line(screen, hp_color, \
                                     (e.rect.left, e.rect.bottom + 5), \
                                     (e.rect.left+e.rect.width*hp_percentage, \
                                      e.rect.bottom + 5), 2)
                else:
                    # Enemy blows up!
                    # Use the delay effect to entend the time interval among
                    # blow up images, make the blow animation better
                    screen.blit(e.destroy_images[mid_destroy_index], e.rect)
                    if not (delay % 3):
                        # Only play the sound once per explosion
                        if mid_destroy_index == 0:
                            enemy2_down_sound.play()
                        # Keep the index value between 0 and 3
                        mid_destroy_index = (mid_destroy_index + 1) % 4
                        if mid_destroy_index == 0:
                            score += 100
                            e.reset()

            # Draw small enemies
            for e in small_enemies:
                if e.alive:
                    e.move()
                    screen.blit(e.image, e.rect)
                else:
                    # Enemy blows up!
                    # Use the delay effect to entend the time interval among
                    # blow up images, make the blow animation better
                    screen.blit(e.destroy_images[small_destroy_index], e.rect)
                    if not (delay % 3):
                        # Only play the sound once per explosion
                        if small_destroy_index == 0:
                            enemy1_down_sound.play()
                        # Keep the index value between 0 and 3
                        small_destroy_index = (small_destroy_index + 1) % 4
                        if small_destroy_index == 0:
                            score += 10
                            e.reset()

            # Draw hero jet
            if me.alive and not me.invincible:
                if switch_image:
                    screen.blit(me.image, me.rect)
                else:
                    screen.blit(me.image1, me.rect)
            elif me.alive and me.invincible:
                if delay % 10 > 4:
                    screen.blit(me.image, me.rect)
            else:
                # Hero jet blows up!
                # Use the delay effect to entend the time interval among
                # blow up images, make the blow animation better
                screen.blit(me.destroy_images[me_destroy_index], me.rect)
                if not (delay % 3):
                    # Only play the sound once per explosion
                    if me_destroy_index == 0:
                        me_down_sound.play()
                    # Keep the index value between 0 and 3
                    me_destroy_index = (me_destroy_index + 1) % 4
                    if me_destroy_index == 0:
                        life -= 1
                        # If has life points, continue playing
                        if life:
                            me.resurrect()
                            pygame.time.set_timer(invincible_timer, 2 * 1000)
                        # No life points left
                        else:
                            print('Game Over!')

        elif not life:
            # Only conduct the following procedure once
            if not terminated:
                terminated = True
                # Terminate some stuff
                pygame.mixer.music.stop()
                pygame.mixer.stop()
                pygame.time.set_timer(supply_timer, 0)

                # Historical highest score
                if not os.path.exists('record.txt'):
                    best_score = 0
                else:
                    with open('record.txt', 'r') as f:
                        best_score = int(f.read())
                        f.close()

                if score > best_score:
                    best_score = score
                    print(best_score)
                    with open('record.txt', 'w') as f:
                        f.write(str(score))
                        f.close()

            #gameover_image = pygame.image.load('image/background.png').convert_alpha()
            final_score_text = final_score_font.render(
                'Final Score: %s' % str(score), True, black)
            best_score_text = score_font.render(
                'Highest Score: {}'.format(best_score), True, black)
            again_image = pygame.image.load('image/again.png').convert_alpha()
            again_rect = again_image.get_rect()
            again_rect.left += 150
            again_rect.top += 400
            screen.blit(background, (0, 0))
            screen.blit(best_score_text, (20, 20))
            screen.blit(final_score_text, (70, 270))
            screen.blit(again_image, again_rect)

        pygame.display.flip()

        clock.tick(60)
    '''
Пример #13
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
Пример #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)
Пример #15
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)
Пример #16
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)
Пример #17
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)

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

        # 绘制大型敌机
        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)
                # 即将出现在画面中,播放音效
                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:
                        me_down_sound.stop()
                        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_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)
Пример #18
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帧
Пример #19
0
def main():

    # =============Set background image==============
    background = pygame.image.load(
        "image/background.png")  # Load background image
    gameover_image = pygame.image.load(
        "image/game_over.png")  # game over background image
    gameover_rect = gameover_image.get_rect()
    game_over = False
    restart_button_normal = pygame.image.load("image/restart.png")
    restart_button_hover = pygame.image.load("image/restart_hover.png")
    restart_button_rect = restart_button_normal.get_rect()
    restart_button_rect.left, restart_button_rect.top = (170, 500)

    x = 0  # Set the initial background position
    y = 0
    x1 = 0
    y1 = -HEIGHT

    # ==============Create enemy plane instances==============
    enemies = pygame.sprite.Group()  # Creating all enemy plane groups
    small_enemies = pygame.sprite.Group()  # Creating small enemy plane group
    add_small_enemies(small_enemies, enemies, 1)
    mid_enemies = pygame.sprite.Group()  # Create middle enemy plane group
    add_mid_enemies(mid_enemies, enemies, 1)
    big_enemies = pygame.sprite.Group()  # Create big enemy plane group
    add_big_enemies(big_enemies, enemies, 1)
    small_enemies2 = pygame.sprite.Group()  # Creating small enemy plane group
    add_small_enemies2(small_enemies2, enemies, 1)
    sp_enemies = pygame.sprite.Group()  # Creating special enemy plane group
    add_sp_enemies(sp_enemies, enemies,
                   0)  # No special enemy at very begaining
    bosses = 0  # Control the special enemy plane
    supplies = pygame.sprite.Group()

    # ==============Initializing my plane==============
    me = myplane.MyPlane(bg_size)
    switch_image = False

    # ===============user score=================
    score = 0
    score_font = pygame.font.SysFont("Chalkboard", 24)
    game_over_player_score_font = pygame.font.SysFont("Chalkboard", 48)
    high_score_font = pygame.font.SysFont("Chalkboard", 36)

    # =========== current game difficulty level ===========
    level = 1

    # ===============Create all the bullets=================
    bullets = []  # Generate my bullets
    bullet_index = 0
    bullet_num = 200  # Amount of bullet instances
    for i in range(bullet_num):
        bullets.append(bullet.MyBullet())

    bullets2 = []  # Generate enemy bullets of middle enemy
    bullet2_index = 0
    bullet2_num = 200
    for i in range(bullet2_num):
        bullets2.append(bullet.EnemyBullet1())

    bullets3 = []  # Generate enemy bullets of big enemy
    bullet3_index = 0
    bullet3_num = 200
    for i in range(bullet3_num):
        bullets3.append(bullet.EnemyBullet2())

    bullets4 = []  # Generate enemy bullets of laser
    bullet4_index = 0
    bullet4_num = 200
    for i in range(bullet4_num):
        bullets4.append(bullet.Laser())

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                exit()

        me.shooting_time_index += 1  # Shooting time index of my plane increase by 1 in every frame

        # =================Control the plane=================
        control_plane_x = 0
        control_plane_y = 0
        if me.active:
            key_pressed = pygame.key.get_pressed()  # Get user input sequence
            if key_pressed[K_w] or key_pressed[K_UP]:
                control_plane_y = 1
            if key_pressed[K_s] or key_pressed[K_DOWN]:
                control_plane_y = -1
            if key_pressed[K_a] or key_pressed[K_LEFT]:
                control_plane_x = -1
            if key_pressed[K_d] or key_pressed[K_RIGHT]:
                control_plane_x = 1
            movement_angle = atan2(control_plane_y, control_plane_x)
            if control_plane_x == 0 and control_plane_y == 0:
                me.move(movement_angle, False)
            else:
                me.move(movement_angle, True)

                # ==============special add===============

                # ==============Game difficulty level================
            if level == 1 and score > 3000:
                # If reaching level 2, add 3 small enemies, 2 middle enemies and 1 big enemies.
                # Increase the speed of small enemy.
                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)
                increase_speed(small_enemies, 1)
            elif level == 2 and bosses == 0:
                #sp_enemy_ap.play()
                add_sp_enemies(sp_enemies, enemies, 1)
                bosses = 1
            elif level == 2 and score > 12000 and bosses == 1:  # Reaching level 3
                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)
                increase_speed(small_enemies, 1)
                increase_speed(mid_enemies, 1)
            elif level == 3 and bosses == 1:
                #sp_enemy_ap.play()
                add_sp_enemies(sp_enemies, enemies, 1)
                bosses = 2
            elif level == 3 and score > 60000 and bosses == 2:  # Reacin level 4
                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)
                increase_speed(small_enemies, 1)
                increase_speed(mid_enemies, 1)
                increase_speed(big_enemies, 1)

        # ============Set the background to scroll (repeatedly blit same two images)========
        screen.blit(background, (x, y))
        screen.blit(background, (x1, y1))
        y1 += 3
        y += 3
        if y > HEIGHT:
            y = -HEIGHT
        if y1 > HEIGHT:
            y1 = -HEIGHT

        # =========Shooting bullets according to different bullet levels of my plane==========
        if me.active:
            if me.bullet_level <= 3:
                if me.bullet_level == 1:
                    bullet.MyBullet.shooting_interval = 20
                elif me.bullet_level == 2:
                    bullet.MyBullet.shooting_interval = 15
                elif me.bullet_level == 3:
                    bullet.MyBullet.shooting_interval = 11
                if me.shooting_time_index % bullet.MyBullet.shooting_interval == 0:  # Shoot a bullet at a certain interval
                    bullet_sound.play()
                    bullets[bullet_index].shoot(me.rect.midtop)
                    bullet_index = (bullet_index + 1) % bullet_num
            elif 4 <= me.bullet_level <= 6:
                if me.bullet_level == 4:
                    bullet.MyBullet.shooting_interval = 17
                elif me.bullet_level == 5:
                    bullet.MyBullet.shooting_interval = 12
                elif me.bullet_level == 6:
                    bullet.MyBullet.shooting_interval = 8
                if me.shooting_time_index % bullet.MyBullet.shooting_interval == 0:
                    bullet_sound.play()
                    bullets[bullet_index].shoot(
                        (me.rect.centerx - 35, me.rect.centery))
                    bullets[bullet_index + 1].shoot(
                        (me.rect.centerx + 28, me.rect.centery))
                    bullet_index = (bullet_index + 2) % bullet_num
                    if bullet_index >= bullet_num - 1:
                        bullet_index = 0

            elif 7 <= me.bullet_level <= 9:
                if me.bullet_level == 7:
                    bullet.MyBullet.shooting_interval = 9
                elif me.bullet_level == 8:
                    bullet.MyBullet.shooting_interval = 7
                elif me.bullet_level == 9:
                    bullet.MyBullet.shooting_interval = 4
                if me.shooting_time_index % bullet.MyBullet.shooting_interval == 0:
                    bullet_sound.play()
                    bullets[bullet_index].shoot(
                        (me.rect.centerx - 33, me.rect.centery), 105)
                    bullets[bullet_index + 1].shoot(
                        (me.rect.centerx - 6, me.rect.centery), 90)
                    bullets[bullet_index + 2].shoot(
                        (me.rect.centerx + 28, me.rect.centery), 75)
                    bullet_index = (bullet_index + 3) % bullet_num
                    if bullet_index >= bullet_num - 2:
                        bullet_index = 0

            elif me.bullet_level == 10:
                bullet.MyBullet.shooting_interval = 4
                if me.shooting_time_index % bullet.MyBullet.shooting_interval == 0:
                    bullet_sound.play()
                    bullets[bullet_index].shoot(
                        (me.rect.centerx - 33, me.rect.centery), 120)
                    bullets[bullet_index + 1].shoot(
                        (me.rect.centerx - 6, me.rect.centery), 90)
                    bullets[bullet_index + 2].shoot(
                        (me.rect.centerx + 28, me.rect.centery), 60)
                    bullets[bullet_index + 3].shoot(
                        (me.rect.centerx + 20, me.rect.centery), 75)
                    bullets[bullet_index + 4].shoot(
                        (me.rect.centerx - 25, me.rect.centery), 105)
                    bullet_index = (bullet_index + 5) % bullet_num
                    if bullet_index >= bullet_num - 4:
                        bullet_index = 0

        # ================The move of the bullets===========
        if me.active:
            for b in bullets:
                if b.active:
                    if me.bullet_level == 1 or me.bullet_level == 4 or me.bullet_level == 7:
                        b.move()
                        bullet_image = b.image1
                    elif me.bullet_level == 2 or me.bullet_level == 5 or me.bullet_level == 8:
                        b.move()
                        bullet_image = b.image2
                    elif me.bullet_level == 3 or me.bullet_level == 6 or me.bullet_level == 9 or me.bullet_level == 10:
                        b.move()
                        bullet_image = b.image3
                    screen.blit(bullet_image, b.rect)

        # ================Collision between the bullets and enemy planes============
        for b in bullets:
            if b.active:
                enemies_hit = pygame.sprite.spritecollide(
                    b, enemies, False, pygame.sprite.collide_mask)
                if enemies_hit:
                    b.active = False
                    for e in enemies_hit:
                        e.energy -= 1
                        e.hit = True  # Plane is hit
                        if e.energy == 0:
                            e.active = False

        # =========Detect whether my plane touches bullets2===========
        if me.active:
            bullets2_hit = pygame.sprite.spritecollide(
                me, bullets2, False, pygame.sprite.collide_mask)
            for b in bullets2_hit:
                if b.active:
                    me.hit = True
                    me.life -= 10
                    b.active = False

        # =========Detect whether my plane touches bullets3===========
        if me.active:
            bullets3_hit = pygame.sprite.spritecollide(
                me, bullets3, False, pygame.sprite.collide_mask)
            for b in bullets3_hit:
                if b.active:
                    me.hit = True
                    me.life -= 30
                    b.active = False

        # =========Detect whether my plane touches bullets4===========
        if me.active:
            bullets4_hit = pygame.sprite.spritecollide(
                me, bullets4, False, pygame.sprite.collide_mask)
            for b in bullets4_hit:
                if b.active:
                    me.hit = True
                    me.life -= 100
                    b.active = False

        # =====Detect whether there is a collision between my plane and enemy planes======
        if me.active:
            enemies_down = pygame.sprite.spritecollide(
                me, enemies, False, pygame.sprite.collide_mask)
            if enemies_down:  # If the list of collision detection is not empty, then collision happens.
                for e in enemies_down:
                    if e.active:
                        me.life -= e.crashing_power
                        e.active = False  # Enemy plane destroyed

        # =====Detect whether the plane touches the supply======
        if me.active:
            supplies_got = pygame.sprite.spritecollide(
                me, supplies, True, pygame.sprite.collide_mask)
            for s in supplies_got:
                if s.show:
                    get_bomb_sound.play()
                    if isinstance(s, supply.BulletSupply):
                        me.bullet_level += 1
                        if me.bullet_level >= 10:
                            me.bullet_level = 10
                    s.show = False

        # =========Blit the special enemies and have them move==========
        for each in sp_enemies:
            if each.active:
                each.sp_move(each.shooting_time_index)
                each.shooting_time_index += 1
                screen.blit(each.image, each.rect)
                timesp = (each.shooting_time_index - 70) % 400
                if timesp < 40:
                    if timesp % (
                            bullet.EnemyBullet2.shooting_interval //
                            10) == 0:  # Shoot a bullet at a certain interval
                        bullet3_angle = (180 / pi) * atan2(
                            (each.rect.centery - me.rect.centery),
                            (me.rect.centerx - each.rect.centerx))
                        bullets3[bullet3_index].shoot(
                            (each.rect.centerx - 10, each.rect.centery),
                            bullet3_angle)  # Big enemy shooting bullets
                        bullet3_index = (bullet3_index + 1) % bullet3_num
                elif timesp >= 90 and timesp < 190:
                    if timesp == 90:
                        bullets4[bullet4_index].shoot(
                            (each.rect.centerx - 13, each.rect.centery + 55),
                            -90)
                        bullet4_index = (bullet4_index + 1) % bullet4_num
                elif timesp >= 220 and timesp < 320:
                    if timesp % (bullet.EnemyBullet2.shooting_interval //
                                 5) == 0:
                        bullets3[bullet3_index].shoot(
                            (each.rect.centerx - 10, each.rect.centery), -36)
                        bullets3[bullet3_index + 1].shoot(
                            (each.rect.centerx - 10, each.rect.centery), -72)
                        bullets3[bullet3_index + 2].shoot(
                            (each.rect.centerx - 10, each.rect.centery), -108)
                        bullets3[bullet3_index + 3].shoot(
                            (each.rect.centerx - 10, each.rect.centery), -144)
                        bullet3_index = (bullet3_index + 4) % bullet3_num

                # ================The move of the laser from special enemy===========-
                for b in bullets4:
                    if b.active:
                        b.movesp(each.shooting_time_index)
                        screen.blit(b.image, b.rect)

        # =========Blit the big enemies and have them move==========
        for each in big_enemies:
            if each.active:
                each.move()
                each.shooting_time_index += 1
                screen.blit(
                    animation_frame("big_enemy_{}".format(id(each)),
                                    each.images, 3), each.rect)
                if each.shooting_time_index % bullet.EnemyBullet2.shooting_interval == 0:  # Shoot a bullet at a certain interval
                    bullet3_angle = (180 / pi) * atan2(
                        (each.rect.centery - me.rect.centery),
                        (me.rect.centerx - each.rect.centerx))
                    bullets3[bullet3_index].shoot(
                        (each.rect.centerx - 10, each.rect.centery),
                        bullet3_angle)  # Big enemy shooting bullets
                    bullet3_index = (bullet3_index + 1) % bullet3_num

        # =========Blit the mid enemies and have them move==========
        for each in mid_enemies:
            if each.active:
                each.move()
                each.shooting_time_index += 1
                screen.blit(each.image, each.rect)
                if each.shooting_time_index % bullet.EnemyBullet1.shooting_interval == 0:  # Shoot a bullet at a certain interval
                    bullets2[bullet2_index].shoot(
                        (each.rect.centerx - 3, each.rect.centery),
                        -90)  # Shooting bullets by middle enemy
                    bullet2_index = (bullet2_index + 1) % bullet2_num

        # =========Blit the small enemies and have them move==========
        for each in small_enemies:
            if each.active:
                each.move()
                screen.blit(each.image, each.rect)

        # =========Blit the small enemies2 and have them move==========
        for each in small_enemies2:
            if each.active:
                if each.init_position_left < 0:
                    each.move(-60)
                else:
                    each.move(-120)
                screen.blit(each.image, each.rect)

        # =========When the special enemy is hit==============
        for each in sp_enemies:
            if each.active:
                if each.hit:
                    screen.blit(each.image_hit, each.rect)
                    each.hit = False

        # =========When the big enemy is hit==============
        for each in big_enemies:
            if each.active:
                if each.hit:
                    screen.blit(each.image_hit, each.rect)
                    each.hit = False

        # =========When the middle enemy is hit==============
        for each in mid_enemies:
            if each.active:
                if each.hit:
                    screen.blit(each.image_hit, each.rect)
                    each.hit = False

        # =========When enemy is destroyed===========
        for each in enemies:
            destroy_sound = globals()["{}_destroy_sound".format(
                each.__class__.__name__)]
            destroy_frame_len = len(each.destroy_images)
            if not each.active:
                destroy_sound.play()
                screen.blit(
                    animation_frame("enemy_{}".format(id(each)),
                                    each.destroy_images, destroy_frame_len),
                    each.rect)
                if all_animation.get("enemy_{}".format(id(each))).is_finished:
                    score += each.destroy_score
                    if getattr(each, "supply", False):
                        each.supply.drop(
                            ((each.rect.centerx - each.supply.rect.width / 2),
                             each.rect.centery
                             ))  # Dropping supplies when destroyed
                        supplies.add(each.supply)
                    each.reset()

        # ================The move of the bullets from big enemy===========-
        for b in bullets3:
            if b.active:
                b.move()
                screen.blit(b.image, b.rect)

        # ================The move of the bullets from middle enemy===========-
        for b in bullets2:
            if b.active:
                b.move()
                screen.blit(b.image, b.rect)

        # =============The move of the supplies===============
        for each in supplies:
            if each.show:
                each.move(bg_size)
                screen.blit(each.image, each.rect)

        # ========Draw the plane and switch between two images to realize the air-jetting effect======
        if me.active:
            screen.blit(animation_frame("me", me.images, 3),
                        me.rect)  # Change the image every 3 frames

        # =============When my plane is hit=============
        if me.active:
            if me.hit:
                screen.blit(animation_frame("me_hit", me.images_hit, 1),
                            me.rect)
                if all_animation.get("me_hit").is_finished:
                    me.hit = False

        # =============Display the user score====================
        score_text = score_font.render("Score: {}".format(str(score)), True,
                                       BLACK)
        screen.blit(score_text, (10, 40))

        # =============Draw the remaining blood of my plane================
        pygame.draw.line(screen, (75, 75, 75), (10, 20), (200, 20), 30)
        if me.life / 100 > 0.3:
            energy_color = GREEN
        elif 0.15 <= me.life / 100 <= 0.3:
            energy_color = YELLOW
        elif 0 <= me.life / 100 < 0.15:
            energy_color = RED
        pygame.draw.line(screen, energy_color, (10, 20),
                         ((me.life / 100) * 190 + 11, 20), 30)
        blood_bar = Rect(10, 20, 190, 20)

        # =============Detect whether my plane is destroyed==============
        if game_over == False:
            if me.life <= 0:
                me.life = 0
                me.active = False
                # When my plane is destroyed, create the animation
                screen.blit(
                    animation_frame("me_destroy", me.destroy_images, 5),
                    me.rect)

        # =============Show the game over screen============
        if me.active == False:
            if all_animation.get("me_destroy").is_finished:
                game_over = True

        # =============When game over==============
        if game_over:  # Detect the restart button
            restart_button = restart_button_normal
            if restart_button_rect.collidepoint(pygame.mouse.get_pos()):
                restart_button = restart_button_hover
                for event in pygame.event.get():
                    if event.type == MOUSEBUTTONDOWN:
                        game_over = False
                        pygame.mixer.music.play(-1)
                        main()

            with open("high_score.txt",
                      "r") as f:  # Load the high score data from txt file
                high_score = int(f.read())
            if score > high_score:  # If player's scoring is higher, then save it
                with open("high_score.txt", "w") as f:
                    f.write(str(score))
            player_score_text = game_over_player_score_font.render(
                "{}".format(score), True, WHITE)
            high_score_text = high_score_font.render("{}".format(high_score),
                                                     True, WHITE)
            screen.blit(gameover_image, gameover_rect)  # Show game over screen
            screen.blit(player_score_text, (230, 210))
            screen.blit(high_score_text, (230, 390))
            screen.blit(restart_button, restart_button_rect)
            pygame.mixer.music.stop()  # Stop the background music

        pygame.display.flip()
        clock.tick(frame_rate)  # Set the frame rate to 60
Пример #20
0
def main():
    # 播放音乐
    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/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

    # 设置难度
    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_time(DOUBLE_BULLTET_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(target=small_enemies, inc=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(target=small_enemies, inc=1)
            inc_speed(target=mid_enemies, inc=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(target=small_enemies, inc=1)
            inc_speed(target=mid_enemies, inc=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(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 += 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 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 += 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:
                        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 += 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 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_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 % 11):
            switch_plane = not switch_plane

        delay -= 1
        if not delay:
            delay = 100

        pygame.display.flip()
        clock.tick(60)
Пример #21
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)
Пример #22
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)
Пример #23
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()
Пример #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()
	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帧
Пример #25
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)
Пример #26
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)
Пример #27
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
    #######################
    stopping_img = pygame.image.load("images/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
    #########################
    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_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 == INVINCEBLE_TIME:
                me.invincible = False
                pygame.time.set_timer(INVINCEBLE_TIME, 0)

        # 根据用户的得分增加难度
        if level == 1 and score > 30000:
            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 > 100000:
            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 > 500000:
            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()
            if key_pressed[K_s] or key_pressed[K_DOWN]:
                me.moveDown()
            if key_pressed[K_a] or key_pressed[K_LEFT]:
                me.moveLeft()
            if key_pressed[K_d] or key_pressed[K_RIGHT]:
                me.moveRight()

            # 检测我方飞机是否被撞
            enemies_down = pygame.sprite.spritecollide(
                me, enemies, False, pygame.sprite.collide_mask)
            if enemies_down and not me.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())
                with open("recordname.txt", "r") as f:
                    record_name = str(f.read())
                if score > record_score:
                    with open("record.txt", "w") as f:
                        f.write(str(score))
                    with open("records.txt", "r") as f:
                        record_bestname = str(f.read())
                    with open("recordname.txt", "w") as f:
                        f.write(str(record_bestname))
            # 绘制结束画面
            record_score_text = score_font.render(
                "Best: %d User_Name:%s" % (record_score, record_name), 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)
Пример #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, 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)
Пример #29
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 = 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.centerx+0, 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

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

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

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

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

    # 生命数量
    life_image = pygame.image.load("images/link.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 == SUPPLY_TIME:
                supply_sound.play()
                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 key_pressed[K_u]:
                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)

            if(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)
            if(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)
            if(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)
            if key_pressed[K_p]:
                level=level+1
                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)

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

            # 绘制超级子弹补给并检测是否获得
            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))
                    bullets[bullet2_index + 2].reset((me.rect.centerx + 0, me.rect.centery))
                    bullet2_index = (bullet2_index + 3) % 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)

            # 绘制剩余生命数量
            if life_num:
                for i in range(life_num):
                    screen.blit(life_image, \
                                (i  * life_rect.width, \
                                 height - 10 - life_rect.height))

            # 绘制得分
            score_text = score_font.render("Score : %s" % str(score), False, 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)
Пример #30
0
def main():
    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_NUM = 4  #估计4颗子弹就能占据频幕80%长度
    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 + 33, 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)  #字体及大小

    #游戏说明
    readme_font = pygame.font.Font('font/font.ttf', 24)

    #标志是否暂停游戏
    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()  #恢复所有音效

                #重新开始游戏
                if event.button == 1 and again_rect.collidepoint(event.pos):
                    life_num = 3
                    score = 0
                    pygame.mixer.music.play()
                    pygame.mixer.init()
                    pygame.time.set_timer(SUPPLY_TIME, 30 * 1000)
                    #初始化敌机
                    for each in enemies:
                        each.reset()
                    #初始化我方飞机
                    me.reset()

                #游戏结束退出
                if event.button == 1 and gameover_rect.collidepoint(event.pos):
                    pygame.quit()
                    sys.exit()

            #检测鼠标指针是否在按钮上
            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 paused:
            f = open('readme.txt', 'r')
            f.readline()
            y = 100
            for each in f:
                line = each.split('\n')[0]
                line_txt = readme_font.render(line, True, WHITE)
                screen.blit(line_txt, (30, y))
                y += 40

        #主流程
        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()
                    #发射超级子弹18秒
                    is_double_bullet = True
                    pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000)
                    bullet_supply.active = False

            #绘制子弹,10帧一射
            if not (delay % 10):
                bullet_sound.play()
                if is_double_bullet:
                    bullets = bullet2
                    bullets[bullet2_index].reset(
                        (me.rect.centerx - 33, me.rect.centery))
                    bullets[bullet2_index + 1].reset(
                        (me.rect.centerx + 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

            #绘制大型敌机
            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  #小技巧,只取0到5
                        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 e1_destroy_index == 0:
                            enemy2_down_sound.play()
                        screen.blit(each.destroy_images[e2_destroy_index],
                                    each.rect)
                        e3_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

            #绘制我方飞机
            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):
                    #只播放一次音效
                    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('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))

            #绘制得分,将文字渲染成surface对象
            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') 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, (25, 25))

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