Commits

Radomir Dopieralski committed 40dbadd

Move to next level when all black jellies are killed

  • Participants
  • Parent commits 93c6faa

Comments (0)

Files changed (6)

jelly/__init__.py

         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:
             return
         if choice == 1:
             raise util.QuitLevel()
+        if choice == 2:
+            raise util.QuitGame()
 
     def main(self):
         self.pc = mobs.Player()
                 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()
                 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:
 
 from jelly import sprites
 from jelly import resource
+from jelly import message
 
 
 class SortedUpdates(pygame.sprite.RenderUpdates):
             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)
                     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)
             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))
 
 
 from jelly.util import DX, DY
+from jelly import mobs
 
 
 class Error(Exception):
 
         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:
     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):
         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:
     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))
         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
 
         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
     Sprite = sprites.MobSprite
     has_light = False
     max_hp = 2
+    hunted = False
     behaviors = [attack_behavior, wander_behavior]
 
     def __init__(self, (x, y)):
 class PinkJelly(Mob):
     name = 'pink jelly'
     color = 2
+    max_hp = 3
     animation = [56, 56, 57, 57, 57, 57]
     behaviors = [attack_behavior, coward_behavior]
 
 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]
 
 class RedJelly(Mob):
     name = 'red jelly'
     color = 3
+    max_hp = 1
     animation = [66, 66, 67, 67, 67]
     behaviors = [attack_behavior, aggressive_behavior]
 
 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]
 
 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):
     def hit(self, level, attacker):
         level.open(self)
 
-
 class Ladder(Mob):
     name = 'ladder'
     animation = [95, 96] * 7
     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):
             display.update()
             display.draw()
             choice = menu.update()
-        display.refresh()
 
     def control(self, level, display):
         direction = None
         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
         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__()
             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):