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
Binary file blow/beast.png has changed
Binary file blow/boss.png has changed
Binary file blow/effects.png has changed
--- 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)
 
Binary file blow/hero.png has changed
Binary file blow/skeleton.png has changed