changeset 22:40dbaddd1239

Move to next level when all black jellies are killed
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Thu, 15 Mar 2012 23:02:19 +0100
parents 93c6faab5f90
children 66a1869d2851
files jelly/__init__.py jelly/display.py jelly/level.py jelly/message.py jelly/mobs.py jelly/sprites.py
diffstat 6 files changed, 105 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/jelly/__init__.py	Thu Mar 15 21:25:50 2012 +0100
+++ b/jelly/__init__.py	Thu Mar 15 23:02:19 2012 +0100
@@ -66,7 +66,9 @@
         self.display.render_level(self.level)
 
     def quit_menu(self):
-        menu = message.Menu((200, 100), ['Continue playing', 'Exit to title'])
+        menu = message.Menu(
+                (290, 200),
+                ['Continue playing', 'Quit to title', 'Exit game'])
         self.display.render_menu(menu)
         choice = None
         try:
@@ -79,6 +81,8 @@
             return
         if choice == 1:
             raise util.QuitLevel()
+        if choice == 2:
+            raise util.QuitGame()
 
     def main(self):
         self.pc = mobs.Player()
@@ -93,7 +97,7 @@
                 if event.type == pg.QUIT:
                     raise util.QuitGame()
                 elif event.type == pg.KEYDOWN and event.key == pg.K_n:
-                    self.next_level()
+                    self.level.hunted = 0
                 elif event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
                     self.quit_menu()
                     self.display.refresh()
@@ -104,6 +108,8 @@
                 self.display.events(self.level.events)
                 self.level.events = []
             if not pc_animation:
+                if self.level.is_level_over and self.next_level():
+                    return True
                 if self.pc.control(self.level, self.display):
                     for mob in list(self.level.mobs):
                         if mob == self.pc:
--- a/jelly/display.py	Thu Mar 15 21:25:50 2012 +0100
+++ b/jelly/display.py	Thu Mar 15 23:02:19 2012 +0100
@@ -9,6 +9,7 @@
 
 from jelly import sprites
 from jelly import resource
+from jelly import message
 
 
 class SortedUpdates(pygame.sprite.RenderUpdates):
@@ -111,7 +112,7 @@
             self.first_draw = False
         else:
             if self.fog:
-                self.hud.clear(self.screen, self.memory)
+                self.hud.clear(self.fog, self.memory)
                 self.lights.clear(self.fog, self.memory)
                 visible = self.lights.draw(self.fog)
                 self.dirty.extend(visible)
@@ -119,8 +120,10 @@
                     self.screen.blit(self.background, rect.topleft, rect)
                 self.shadows.draw(self.screen)
                 self.sprites.draw(self.screen)
+                self.dirty.extend(self.hud.draw(self.screen))
                 for rect in self.dirty:
                     self.screen.blit(self.fog, rect.topleft, rect)
+                self.hud.draw(self.screen)
             else:
                 self.hud.clear(self.screen, self.background)
                 self.sprites.clear(self.screen, self.background)
@@ -208,6 +211,18 @@
             sprite = self.mob_sprites[id(spawner)]
             sprite.set_animation(sprite.spawner_animation())
 
+    def on_mob_message(self, mob, text):
+        try:
+            sprite = self.mob_sprites[id(mob)]
+        except KeyError:
+            return
+        msg = message.Message(text, sprite.rect.midbottom)
+        msg.depth = sprite.depth
+        self.sprites.add(msg)
+
+    def on_mob_finish(self, mob):
+        sprite = self.mob_sprites[id(mob)]
+        sprite.set_animation(sprite.finish_animation())
 
 def render_background(level, tiles):
     background = pygame.Surface((level.width * 20 + 20, level.height * 12 + 20))
--- a/jelly/level.py	Thu Mar 15 21:25:50 2012 +0100
+++ b/jelly/level.py	Thu Mar 15 23:02:19 2012 +0100
@@ -3,6 +3,7 @@
 
 
 from jelly.util import DX, DY
+from jelly import mobs
 
 
 class Error(Exception):
@@ -35,6 +36,8 @@
 
         self.events = []
         self.is_game_over = False
+        self.is_level_over = False
+        self.hunted = 0
 
     def __getitem__(self, (x, y)):
         if self.width > x >= 0 and self.height > y >= 0:
@@ -68,10 +71,21 @@
     def spawn(self, mob, spawner=None):
         self.mobs.append(mob)
         self.events.append(('mob_spawn', mob, spawner))
+        if mob.hunted:
+            self.hunted += 1
 
     def kill(self, mob):
         self.mobs.remove(mob)
         self.events.append(('mob_death', mob))
+        if mob.hunted:
+            self.hunted -= 1
+            if self.hunted <= 0:
+                ladder = mobs.Ladder2(self.pc.pos)
+                self.is_level_over = True
+                self.spawn(ladder)
+                self.events.append(('mob_finish', self.pc))
+            else:
+                self.message(mob, '%d left' % self.hunted)
 
     def hit(self, mob, attacker):
         if mob.hit(self, attacker):
@@ -81,6 +95,8 @@
         self.mobs.remove(mob)
         self.events.append(('mob_open', mob))
         self.events.append(('mob_dust', mob, 10, 4))
+        self.message(mob, 'Empty')
+
 
     def stand(self, mob, direction, dust=False):
         if direction is None:
@@ -101,3 +117,6 @@
     def game_over(self):
         self.events.append(('mob_death', self.pc))
         self.is_game_over = True
+
+    def message(self, mob, text):
+        self.events.append(('mob_message', mob, text))
--- a/jelly/message.py	Thu Mar 15 21:25:50 2012 +0100
+++ b/jelly/message.py	Thu Mar 15 23:02:19 2012 +0100
@@ -38,6 +38,22 @@
         return image
 
 
+class Message(Text):
+    def __init__(self, text, pos):
+        super(Message, self).__init__(text)
+        self.rect.center = pos
+        self.step = 0
+        self.alpha = 255
+
+    def update(self):
+        self.rect.move_ip(0, -2)
+        self.alpha -= 16
+        if self.alpha <= 0:
+            self.kill()
+        else:
+            self.image.set_alpha(self.alpha)
+
+
 class Window(pygame.sprite.Sprite):
     tiles = None
 
@@ -49,16 +65,17 @@
         self.image = pygame.surface.Surface((width, height))
         self.image.set_colorkey((0, 0, 0))
         self.image.fill((25, 100, 252), (4, 4, width - 8, height - 8))
-        for y in xrange(8, height - 8, 8):
-            self.image.blit(tile, (0, y), (0, 8, 8, 8))
-            self.image.blit(tile, (width - 8, y), (24, 8, 8, 8))
-        for x in xrange(8, width - 8, 8):
-            self.image.blit(tile, (x, 0), (8, 0, 8, 8))
-            self.image.blit(tile, (x, height - 8), (8, 24, 8, 8))
+        for y in xrange(8, height - 8, 4):
+            self.image.blit(tile, (0, y), (0, 8, 8, 4))
+            self.image.blit(tile, (width - 8, y), (24, 8, 8, 4))
+        for x in xrange(8, width - 8, 4):
+            self.image.blit(tile, (x, 0), (8, 0, 4, 8))
+            self.image.blit(tile, (x, height - 8), (8, 24, 4, 8))
         self.image.blit(tile, (0, 0), (0, 0, 8, 8))
         self.image.blit(tile, (width - 8, height - 8), (24, 24, 8, 8))
         self.image.blit(tile, (width - 8, 0), (24, 0, 8, 8))
         self.image.blit(tile, (0, height - 8), (0, 24, 8, 8))
+        self.image.set_alpha(92)
 
         self.rect = self.image.get_rect()
         self.rect.topleft = pos
--- a/jelly/mobs.py	Thu Mar 15 21:25:50 2012 +0100
+++ b/jelly/mobs.py	Thu Mar 15 23:02:19 2012 +0100
@@ -106,6 +106,7 @@
     Sprite = sprites.MobSprite
     has_light = False
     max_hp = 2
+    hunted = False
     behaviors = [attack_behavior, wander_behavior]
 
     def __init__(self, (x, y)):
@@ -129,6 +130,7 @@
 class PinkJelly(Mob):
     name = 'pink jelly'
     color = 2
+    max_hp = 3
     animation = [56, 56, 57, 57, 57, 57]
     behaviors = [attack_behavior, coward_behavior]
 
@@ -136,6 +138,7 @@
 class PurpleJelly(Mob):
     name = 'purple jelly'
     color = 1
+    max_hp = 2
     animation = [46, 46, 46, 47, 47, 47, 47]
     behaviors = [attack_behavior, sleep_behavior, wander_behavior]
 
@@ -143,6 +146,7 @@
 class RedJelly(Mob):
     name = 'red jelly'
     color = 3
+    max_hp = 1
     animation = [66, 66, 67, 67, 67]
     behaviors = [attack_behavior, aggressive_behavior]
 
@@ -150,6 +154,7 @@
 class BlueJelly(Mob):
     name = 'blue jelly'
     color = 0
+    max_hp = 5
     animation = [36, 36, 36, 37, 37, 37, 37, 37]
     behaviors = [slow_behavior, attack_behavior, wander_behavior]
 
@@ -157,8 +162,10 @@
 class BlackJelly(Mob):
     name = 'black jelly'
     color = 4
+    max_hp = 3
     animation = [76, 76, 76, 77, 77, 77]
-    behaviors = [one_in(5)(spawn_behavior), wander_behavior]
+    behaviors = [one_in(15)(spawn_behavior), wander_behavior]
+    hunted = True
 
 
 class Crate(Mob):
@@ -171,7 +178,6 @@
     def hit(self, level, attacker):
         level.open(self)
 
-
 class Ladder(Mob):
     name = 'ladder'
     animation = [95, 96] * 7
@@ -183,12 +189,15 @@
     def hit(self, level, attacker):
         pass
 
+class Ladder2(Ladder):
+    Sprite = sprites.Ladder2Sprite
 
 class Player(object):
     name = 'player'
     has_light = True
     Sprite = sprites.PlayerSprite
     animation = None
+    hunted = False
     color = 5
 
     def __init__(self):
@@ -224,7 +233,6 @@
             display.update()
             display.draw()
             choice = menu.update()
-        display.refresh()
 
     def control(self, level, display):
         direction = None
--- a/jelly/sprites.py	Thu Mar 15 21:25:50 2012 +0100
+++ b/jelly/sprites.py	Thu Mar 15 23:02:19 2012 +0100
@@ -15,7 +15,7 @@
         self.image = pygame.Surface((32, 480))
         self.image.set_colorkey((0, 0, 0))
         for step, frame in enumerate(steps):
-            self.image.blit(frames[frame], (0, 32 * step))
+            self.image.blit(frames[frame], (0, 32 * step + 16))
         self.rect = self.image.get_rect()
         self.rect.midbottom = (20 + 20 * x, 32 + 12 * y)
         self.depth = self.rect.bottom
@@ -37,6 +37,22 @@
         pass
 
 
+class Ladder2Sprite(LadderSprite):
+
+    def __init__(self, frames, (x, y), steps):
+        super(Ladder2Sprite, self).__init__(frames, (x,y), steps)
+        self.rect.midbottom = (20 + 20 * x, 32 + 12 * y - 48)
+        self.depth -= 1
+
+    def update(self):
+        self.step += 1
+        if self.step % 4 == 0:
+            self.image = pygame.transform.flip(self.image, True, False)
+            self.step = 0
+        if self.rect.bottom < self.depth:
+            self.rect.move_ip(0, 4)
+
+
 class MobSprite(pygame.sprite.Sprite):
     def __init__(self, frames, (x, y), steps):
         super(MobSprite, self).__init__()
@@ -217,6 +233,17 @@
             frame = [0, 10, 20, 30, 40, 50 ,60, 70][direction]
             self.image = self.frames[frame]
 
+    def finish_animation(self):
+        for step in xrange(8):
+            yield None
+        frames = [40, 40, 41, 41, 42, 42, 43, 43]
+        for ladder in xrange(8):
+            for step in xrange(4):
+                yield None
+                self.frame = (self.frame + 1) % len(frames)
+                self.rect.move_ip(0, -3)
+                self.image = self.frames[frames[self.frame]]
+
 
 class Shadow(pygame.sprite.Sprite):
     def __init__(self, frames, owner):