Mercurial > blow
changeset 11:9964f1c0236c
Dying monsters
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Sun, 28 Apr 2013 21:33:56 +0200 |
| parents | 4df5c37a5da1 |
| children | 2dcb3b6fb6f4 |
| files | blow/beast.png blow/boss.png blow/effects.png blow/game_scene.py blow/hero.png blow/skeleton.png |
| diffstat | 6 files changed, 146 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/blow/game_scene.py Sun Apr 28 16:09:51 2013 +0200 +++ b/blow/game_scene.py Sun Apr 28 21:33:56 2013 +0200 @@ -9,6 +9,7 @@ BOTTOM = 420 +SCROLL = 64 class SlowingSprite(object): def __init__(self, *args, **kwargs): @@ -43,9 +44,13 @@ class JumpingSprite(FallingSprite): + def __init__(self, *args, **kwargs): + super(JumpingSprite, self).__init__(*args, **kwargs) + self.jumping = True + def update(self, tick, scene): super(JumpingSprite, self).update(tick, scene) - if self.on_ground() and self.can_jump(): + if self.jumping and self.on_ground() and self.can_jump(): self.dy = -4 def can_jump(self): @@ -73,6 +78,7 @@ self.depth = 3 self.sword = SwordSprite(self, scene.resources.weapons) scene.sprites.add(self.sword) + self.stunned = False def walk(self, scene, wx): self.rect.move_ip(wx, 0) @@ -89,15 +95,44 @@ def update(self, tick, scene): super(HeroSprite, self).update(tick, scene) - keys = pygame.key.get_pressed() - if keys[pygame.K_LEFT]: - self.walk(scene, -6) - elif keys[pygame.K_RIGHT]: - self.walk(scene, 6) - if keys[pygame.K_UP]: - self.jump(scene) - if keys[pygame.K_SPACE]: - self.swing(scene) + if not self.stunned: + keys = pygame.key.get_pressed() + if keys[pygame.K_LEFT]: + self.walk(scene, -6) + elif keys[pygame.K_RIGHT]: + self.walk(scene, 6) + if keys[pygame.K_UP]: + self.jump(scene) + if keys[pygame.K_SPACE]: + self.swing(scene) + if self.rect.left < SCROLL: + scene.scroll(6, 0) + elif self.rect.right > 768 - SCROLL: + scene.scroll(-6, 0) + + + def stun(self, scene): + self.dy = -8 + self.dx = -6 + self.animation = self.stun_animation(scene) + + def stun_animation(self, scene): + self.image = self.frames[1] + self.bounce = True + self.stunned = True + scene.resources.hit.play() + for i in xrange(30): + yield + self.image = self.frames[0] + self.dx = 0 + self.bounce = False + self.stunned = False + + +class GibSprite(FallingSprite, SlowingSprite, Sprite): + def __init__(self, *args, **kwargs): + super(GibSprite, self).__init__(*args, **kwargs) + self.bouncing = True class MonsterSprite(JumpingSprite, SlowingSprite, Sprite): @@ -105,21 +140,29 @@ super(MonsterSprite, self).__init__(*args, **kwargs) self.depth = 1 self.stunned = False + self.dead = False + self.hp = 2 def update(self, tick, scene): super(MonsterSprite, self).update(tick, scene) + if self.dead: + return if self.stunned and self.on_ground(): scene.resources.hit.play() if self.animation is None and self.can_jump(): - self.animation = random.choice([ - self.walk_left_animation, - self.walk_right_animation, - self.stand_animation, - self.stand_animation, - self.jump_left_animation, - self.jump_right_animation, - self.chomp_animation, - ])(scene) + if abs(self.rect.centerx - scene.hero.rect.centerx) < 48: + animation = self.chomp_animation + else: + animation = random.choice([ + self.walk_left_animation, + self.walk_right_animation, + self.stand_animation, + self.stand_animation, + self.jump_left_animation, + self.jump_right_animation, + self.chomp_animation, + ]) + self.animation = animation(scene) def is_visible(self): return self.rect.right > 0 and self.rect.left < 748 @@ -137,11 +180,16 @@ self.stunned = False def stun(self, scene): - if self.stunned: + if self.stunned or self.dead: return - self.animation = self.stun_animation(scene) self.dx = 12 self.dy = -8 + self.hp -= 1 + if self.hp <= 0: + self.animation = self.die_animation(scene) + else: + self.animation = self.stun_animation(scene) + def walk_left_animation(self, scene): self.image = self.frames[0] @@ -184,45 +232,95 @@ yield yield self.image = self.frames[0] + smash = SmashSprite(scene.resources.effects, frame=1) + smash.rect.midbottom = self.rect.midbottom + scene.sprites.add(smash) yield yield + def die_animation(self, scene): + yield + self.kill() + for frame in xrange(3, 7): + gib = GibSprite(self.frames, frame=frame) + gib.rect.midbottom = self.rect.center + gib.dy = -random.randint(6, 16) + gib.dx = random.randint(4, 16) + scene.sprites.add(gib) + class BossSprite(MonsterSprite): + def __init__(self, *args, **kwargs): + super(BossSprite, self).__init__(*args, **kwargs) + self.depth = 2 + self.invincible = False + self.hp = 5 + def update(self, tick, scene): + if self.dead: + super(MonsterSprite, self).update(tick, scene) + return super(MonsterSprite, self).update(tick, scene) if self.stunned and self.on_ground(): scene.resources.hit.play() if self.animation is None and self.can_jump(): - self.animation = random.choice([ - self.walk_left_animation, - self.walk_right_animation, - self.stand_animation, - self.chomp_animation, - self.chomp_animation, - ])(scene) + if abs(self.rect.centerx - scene.hero.rect.centerx) < 72: + animation = self.chomp_animation + else: + animation = random.choice([ + self.walk_left_animation, + self.walk_right_animation, + self.stand_animation, + self.chomp_animation, + self.chomp_animation, + ]) + self.animation = animation(scene) def chomp_animation(self, scene): + self.invincible = True self.image = self.frames[2] self.dy = -16 self.dx = 0 - while self.dy < -4 or not self.on_ground(): + while not self.rect.bottom > BOTTOM - 8 or self.dy < 0: yield if self.is_visible(): scene.resources.hit.play() - yield - yield - yield - yield + smash = SmashSprite(self.frames, frame=3) + smash.rect.midbottom = self.rect.midbottom + smash.rect.move_ip(0, 32) + scene.sprites.add(smash) + for i in xrange(10): + yield self.image = self.frames[0] + self.invincible = False def stun(self, scene): - if self.stunned: + if self.dead: return - self.animation = self.stun_animation(scene) + if self.stunned or self.invincible: + return self.dx = 6 self.dy = -6 + self.hp -= 1 + if self.hp <= 0: + self.animation = self.die_animation(scene) + else: + self.animation = self.stun_animation(scene) + def die_animation(self, scene): + self.jumping = False + self.invincible = True + self.stunned = True + self.image = self.frames[4] + yield + yield + self.image = self.frames[5] + yield + yield + self.image = self.frames[6] + self.dead = True + for i in xrange(20): + scene.game_over = True class SwordSprite(Sprite): @@ -269,7 +367,7 @@ class SwooshSprite(Sprite): def __init__(self, *args, **kwargs): super(SwooshSprite, self).__init__(*args, **kwargs) - self.image = self.image.copy().convert() + self.image = self.image.subsurface(self.image.get_rect()) self.image.set_alpha(0) self.animation = self.swoosh_animation() self.depth = 9 @@ -291,28 +389,36 @@ monster.stun(scene) +class SmashSprite(SwooshSprite): + def update(self, tick, scene): + super(SwooshSprite, self).update(tick, scene) + if pygame.sprite.collide_mask(self, scene.hero): + scene.hero.stun(scene) + + class GameScene(Scene): def __init__(self, display, resources): super(GameScene, self).__init__(display, resources) self.monsters = pygame.sprite.Group() self.background.fill((0xf2, 0xf0, 0xf4)) - + self.game_over = False self.hero = HeroSprite(self) - self.hero.rect.midbottom = (128, BOTTOM) + self.hero.rect.midbottom = (320, BOTTOM) self.sprites.add(self.hero) - for i in xrange(10): + for i in xrange(26): frames = random.choice([ self.resources.skeleton, self.resources.beast, ]) monster = MonsterSprite(frames) monster.rect.move_ip( - 400 + i * 32, + 400 + i * (128 - i * 3) + random.randint(-64, 64), BOTTOM - random.randint(64, 256), ) self.monsters.add(monster) boss = BossSprite(self.resources.boss) + boss.rect.midbottom = (2048, BOTTOM - 16) self.monsters.add(boss) self.sprites.add(self.monsters)
