class AnimatedSprite(Sprite):
  def __init__(self, image_path, sprite_size, frames = 1, scale = 1, animation_speed = 10, start_frame = 0):
    super().__init__()
    self._sheet, self._sheet_rect = load_image(image_path, scale)

    self.scale = scale
    self.sprite_size = sprite_size
    self.scaled_size = sprite_size * scale
    self.rect = Rect(0, 0, sprite_size * scale, sprite_size * scale)

    self.animation_frame = start_frame
    self.animation_max = frames - 1
    self.animation_speed = animation_speed
    self.animation_timer = Timer()

  def render(self, surface, coords = None):
    coords = coords if coords != None else self.rect
    surface.blit(self._sheet, coords, (self.scaled_size * self.animation_frame, 0, self.scaled_size, self.scaled_size))

  def update(self):
    if self.animation_timer.has_passed(self.animation_speed):
      self.animation_frame = 0 if self.animation_frame == self.animation_max else self.animation_frame + 1
示例#2
0
class Player(AnimatedSprite):
    def __init__(self, scene):
        super().__init__("player.png", 32, 4, 3, 100)
        self.scene = scene
        self.game = self.scene.game
        self.game.events.register_listener('PLAYER_HIT', self.on_hit)

        self.thrust = .8
        self.speed_max = 15
        self.speed_decay = .95
        self.movement_clamp = 10
        self.velocity = pygame.math.Vector2(0, 0)
        self.shoot_delay = 250
        self.shoot_timer = Timer()
        self.shoot_cooldown = False
        self.health = 100
        self.weapon_power = 1

    def on_hit(self, event):
        self.health = max(0, self.health - event.damage)
        self.game.events.broadcast('PLAYER_HEALTH_UPDATE', {})

        if self.health <= 0:
            self.game.events.broadcast('PLAYER_DESTROYED', {})

    def update(self):
        super().update()

        self.move()
        self.shoot()

    def move(self):
        if self.game.input.key(K_LEFT):
            self.velocity.x -= self.thrust
        elif self.game.input.key(K_RIGHT):
            self.velocity.x += self.thrust
        else:
            self.velocity.x *= self.speed_decay

        speed = self.velocity.length()

        if speed > self.speed_max:
            self.velocity.x *= self.speed_max / speed
            self.velocity.y *= self.speed_max / speed
        elif (self.velocity.x > -.5
              and self.velocity.x < 0) or (self.velocity.x < .5
                                           and self.velocity.x > 0):
            self.velocity.x = 0

        if (self.rect.left - self.movement_clamp < 0 and self.velocity.x < 0
                or self.rect.left > self.game.get_width() - self.rect.width -
                self.movement_clamp and self.velocity.x > 0):
            self.velocity.x = 0

        self.rect.move_ip(self.velocity.x, self.velocity.y)

    def shoot(self):
        if self.shoot_cooldown and self.shoot_timer.has_passed(
                self.shoot_delay):
            self.shoot_cooldown = False

        if self.game.input.key(K_SPACE) and not self.shoot_cooldown:
            self.scene.spawn_projectile(
                self.scene.projectiles,
                Laser(self.rect, power=self.weapon_power))
            self.shoot_cooldown = True
            self.shoot_timer.restart()