英雄

英雄精灵

  • 一开始英雄出现在屏幕的水平中间位置,距离屏幕底部 120 像素
  • 每次连发三枚子弹,每隔 0.5 秒发射一次子弹
    • 子弹从英雄的正上方发射沿直线向上方飞行
    • 子弹飞出屏幕后,从精灵组中删除
  • 通过左/右方向键控制英雄在水平方向移动

由此分析,英雄 和 子弹 需分别定义精灵。

plane_main.py__create_sprites 方法中,把英雄定义为了属性,以便于实现之后的碰撞检测和发射子弹等。

self.hero = Hero()
self.hero_group = pygame.sprite.Group(self.hero)
class Hero(GameSprite):
    """英雄精灵"""

    def __init__(self):
        super().__init__("./images/me1.png", 0)
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom - 120
    def update(self):
        self.rect.x += self.speed

        # 超出屏幕检测
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.right > SCREEN_RECT.right:
            self.rect.right = SCREEN_RECT.right

    # 发射子弹
    def fire(self):
        pass

移动英雄

__event_handler(self) 事件监听函数中,添加:

# 返回所有按键的元组,如果某个键被按下,对应的值会是1
keys_pressed = pygame.key.get_pressed()

if keys_pressed[pygame.K_RIGHT]:
    self.hero.speed = 2
elif keys_pressed[pygame.K_LEFT]:
    self.hero.speed = -2
else:
    self.hero.speed = 0

可以简化为:

keys_pressed = pygame.key.get_pressed()
self.hero.speed = (keys_pressed[pygame.K_RIGHT] - keys_pressed[pygame.K_LEFT]) * 2

不过可读性不太好。


子弹

  • 每次连发三枚子弹,每隔 0.5 秒发射一次子弹
  • 子弹从英雄的正上方发射沿直线向上方飞行
  • 子弹飞出屏幕后,从精灵组中删除

定时器

和敌机同理,使用定时器。

HERO_FIRE_EVENT = pygame.USEREVENT + 1
pygame.time.set_timer(HERO_FIRE_EVENT, 500)
elif event.type == HERO_FIRE_EVENT:
    self.hero.fire()

子弹精灵

class Bullet(GameSprite):
    """子弹精灵"""
    
    def __init__(self):
        super().__init__("./images/bullet1.png", -2)
 
    def update(self):
        super().update()
        if self.rect.bottom < 0:
            self.kill()

子弹精灵定义完成之后,在英雄精灵的初始化方法中创建子弹的精灵组:

self.bullets = pygame.sprite.Group()

发射子弹

def fire(self):

    for i in (1, 2, 3):
        bullet = Bullet()
        bullet.rect.bottom = self.rect.y - i * 20
        bullet.rect.centerx = self.rect.centerx
        self.bullets.add(bullet)

碰撞检测

pygame 有提供现成的碰撞检测方法。

def __check_collide(self):

    pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)
    enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
    
    if len(enemies) > 0:
        self.hero.kill()
        PlaneGame.__game_over()

至此,飞机大战游戏基本功能完成。