changeset 39:2475e658d13f

Change animations through level events
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sat, 10 Mar 2012 13:03:32 +0100
parents b637ee420b8a
children 6d38f7032b0d
files mhrok/__init__.py mhrok/display.py mhrok/level.py mhrok/mobs.py mhrok/sprites.py
diffstat 5 files changed, 88 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/mhrok/__init__.py	Sat Mar 10 12:31:08 2012 +0100
+++ b/mhrok/__init__.py	Sat Mar 10 13:03:32 2012 +0100
@@ -41,4 +41,5 @@
                         if mob == self.pc:
                             continue
                         mob.sprite.direction = None
+                self.display.events(self.level.events)
 
--- a/mhrok/display.py	Sat Mar 10 12:31:08 2012 +0100
+++ b/mhrok/display.py	Sat Mar 10 13:03:32 2012 +0100
@@ -79,6 +79,18 @@
                 room = vision.rooms.pop()
                 self.light_room(room)
 
+    def events(self, events):
+        while events:
+            event = events.pop()
+            getattr(self, 'on_%s' % event[0])(*event[1:])
+
+    def on_mob_walk(self, mob, direction):
+        mob.sprite.set_animation(mob.sprite.walk_animation(direction))
+
+    def on_mob_stand(self, mob, direction):
+        mob.sprite.set_animation(mob.sprite.stand_animation(direction))
+
+
 def load_tiles(filename, width, height):
     f = StringIO.StringIO(pkgutil.get_data('mhrok', filename))
     image = pygame.image.load(f, filename).convert()
--- a/mhrok/level.py	Sat Mar 10 12:31:08 2012 +0100
+++ b/mhrok/level.py	Sat Mar 10 13:03:32 2012 +0100
@@ -33,6 +33,8 @@
         self.BlockedWall = BlockedWall
         self.BlockedMob = BlockedMob
 
+        self.events = []
+
     def __getitem__(self, (x, y)):
         if self.width > x >= 0 and self.height > y >= 0:
             return self.map[y][x]
@@ -50,5 +52,8 @@
         if not self[target]:
             raise self.BlockedWall()
         mob.pos = target
+        self.events.append(('mob_walk', mob, direction))
 
-
+    def stand(self, mob, direction):
+        mob.direction = direction
+        self.events.append(('mob_stand', mob, direction))
--- a/mhrok/mobs.py	Sat Mar 10 12:31:08 2012 +0100
+++ b/mhrok/mobs.py	Sat Mar 10 13:03:32 2012 +0100
@@ -7,7 +7,15 @@
 from pygame import locals as pg
 
 from mhrok import sprites
-from mhrok.util import DX, DY
+
+
+KEY_DIRS = {
+    pg.K_UP: 1,
+    pg.K_LEFT: 0,
+    pg.K_DOWN: 3,
+    pg.K_RIGHT: 2,
+}
+
 
 class Mob(object):
     Sprite = sprites.MobSprite
@@ -31,10 +39,12 @@
 
 
 class Bat(Mob):
+    name = 'bat'
     animation = [25, 26]
 
 
 class Chest(Mob):
+    name = 'chest'
     animation = [27]
 
     def control(self, level):
@@ -42,14 +52,18 @@
 
 
 class Skeleton(Mob):
+    name = 'skeleton'
     animation = [35, 35, 35, 36, 36, 36, 35, 35, 35, 37, 37, 37]
 
 
 class Teddybear(Mob):
+    name = 'teddybear'
     animation = [30, 30, 30, 31, 31, 31, 30, 30, 30, 32, 32, 32]
 
 
 class Player(object):
+    name = 'player'
+
     def place(self, (x, y)):
         self.pos = x, y
         self.direction = 3
@@ -61,16 +75,6 @@
         self.vision = sprites.Vision(self.sprite, 64)
         return self.sprite, shadow, self.vision
 
-    def walk(self, level, direction):
-        self.direction = direction
-        try:
-            level.walk(self, direction)
-        except level.Blocked:
-            return False
-        self.sprite.set_animation(self.sprite.walk_animation(direction))
-        print self.pos
-        return True
-
     def control(self, level):
         room = level.find_room(*self.pos)
         if room:
@@ -80,18 +84,21 @@
                 self.vision.rooms.append(room)
         else:
             self.vision.radius = 40
+
         keys = pygame.key.get_pressed()
-
-        if keys[pg.K_UP]:
-            return self.walk(level, 1)
-        elif keys[pg.K_LEFT]:
-            return self.walk(level, 0)
-        elif keys[pg.K_DOWN]:
-            return self.walk(level, 3)
-        elif keys[pg.K_RIGHT]:
-            return self.walk(level, 2)
+        for key, direction in KEY_DIRS.iteritems():
+            if keys[key]:
+                break
         else:
-            self.sprite.set_animation(
-                    self.sprite.stand_animation(self.direction))
+            direction = None
+        if direction is not None:
+            self.direction = direction
+            try:
+                level.walk(self, direction)
+            except level.Blocked:
+                level.stand(self, self.direction)
+                return False
+        else:
+            level.stand(self, self.direction)
             return False
         return True
--- a/mhrok/sprites.py	Sat Mar 10 12:31:08 2012 +0100
+++ b/mhrok/sprites.py	Sat Mar 10 13:03:32 2012 +0100
@@ -8,9 +8,47 @@
 from mhrok.util import DX, DY
 
 
-class PlayerSprite(pygame.sprite.Sprite):
+class MobSprite(pygame.sprite.Sprite):
+    def __init__(self, frames, (x, y), steps):
+        super(MobSprite, self).__init__()
+        self.steps = steps
+        self.frames = frames
+        self.image = self.frames[0]
+        self.rect = self.image.get_rect()
+        self.frame = 0
+        self.rect.move_ip(4 + 20 * x, 12 * y)
+        self.depth = self.rect.bottom
+        self.animation = None
+
+    def update(self):
+        self.frame = (self.frame + 1) % len(self.steps)
+        self.image = self.frames[self.steps[self.frame]]
+        if self.animation:
+            try:
+                self.animation.next()
+            except StopIteration:
+                self.animation = None
+
+    def walk_animation(self, direction):
+        for frame in range(4):
+            yield None
+            self.rect.move_ip((DX[direction]*5, DY[direction]*3))
+            self.depth = self.rect.bottom
+
+    def stand_animation(self, direction):
+        yield None
+
+    def set_animation(self, animation):
+        self.animation = animation
+        try:
+            self.animation.next()
+        except StopIteration:
+            self.animation = None
+
+
+class PlayerSprite(MobSprite):
     def __init__(self, frames, (x, y)):
-        super(PlayerSprite, self).__init__()
+        super(PlayerSprite, self).__init__(frames, (x, y), None)
         self.direction = 0
         self.frames = frames
         self.image = self.frames[0]
@@ -44,12 +82,6 @@
         frame = [5, 10, 15, 0][direction]
         self.image = self.frames[frame]
 
-    def set_animation(self, animation):
-        self.animation = animation
-        try:
-            self.animation.next()
-        except StopIteration:
-            self.animation = None
 
 class Shadow(pygame.sprite.Sprite):
     def __init__(self, frames, owner):
@@ -99,21 +131,3 @@
         self.rect.center = self.owner.rect.center
 
 
-class MobSprite(pygame.sprite.Sprite):
-    def __init__(self, frames, (x, y), animation):
-        super(MobSprite, self).__init__()
-        self.animation = animation
-        self.frames = frames
-        self.image = self.frames[0]
-        self.rect = self.image.get_rect()
-        self.frame = 0
-        self.rect.move_ip(4 + 20 * x, 12 * y)
-        self.depth = self.rect.bottom
-        self.direction = None
-
-    def update(self):
-        self.frame = (self.frame + 1) % len(self.animation)
-        self.image = self.frames[self.animation[self.frame]]
-        if self.direction is not None:
-            self.rect.move_ip((DX[self.direction]*5, DY[self.direction]*3))
-            self.depth = self.rect.bottom