changeset 35:9dc78f2fcca4

basic monster ai
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sat, 10 Sep 2011 10:25:25 +0200
parents 25bf3ec84410
children 105981e7e2d7 26cb0dbf6af1
files level.map qq.py
diffstat 2 files changed, 45 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/level.map	Sat Sep 10 08:38:28 2011 +0200
+++ b/level.map	Sat Sep 10 10:25:25 2011 +0200
@@ -36,6 +36,7 @@
 tile = 1, 3
 sprite = baby.png
 block = true
+monster = true
 
 [>]
 name = stairs
--- a/qq.py	Sat Sep 10 08:38:28 2011 +0200
+++ b/qq.py	Sat Sep 10 10:25:25 2011 +0200
@@ -95,6 +95,7 @@
     """Sprite for animated items and base class for Player."""
 
     is_player = False
+    is_monster = False
 
     def __init__(self, pos=(0, 0), frames=None):
         super(Sprite, self).__init__()
@@ -104,6 +105,7 @@
         self.rect = self.image.get_rect()
         self.animation = self.stand_animation()
         self.pos = pos
+        self._set_pos(pos)
 
     def _get_pos(self):
         """Check the current position of the sprite on the map."""
@@ -116,7 +118,7 @@
         self.rect.midbottom = pos[0]*24+12, pos[1]*16+16
         self.depth = self.rect.midbottom[1]
 
-    pos = property(_get_pos, _set_pos)
+    #pos = property(_get_pos, _set_pos)
 
     def move(self, dx, dy):
         """Change the position of the sprite on screen."""
@@ -137,7 +139,40 @@
     def update(self, *args):
         """Run the current animation."""
 
-        self.animation.next()
+        try:
+            self.animation.next()
+        except StopIteration:
+            self.animation = self.stand_animation()
+            self.animation.next()
+
+
+class Monster(Sprite):
+    is_monster = True
+
+    def __init__(self, pos=(1, 1), frames=None):
+        Sprite.__init__(self, pos, frames)
+        self.direction = 2
+
+    def ai(self, level):
+        x, y = self.pos
+        self.direction = 2
+        dx, dy = DX[self.direction], DY[self.direction]
+        if level.is_blocking(x + dx, y + dy):
+            return
+        self.pos = x + dx, y + dy
+        self.animation = self.walk_animation()
+        return self.direction
+
+    def walk_animation(self):
+        """Animation for the monster walking."""
+
+        # This animation is hardcoded for 4 frames and 16x24 map tiles
+        for frame in range(4):
+            self.image = self.frames[0][frame]
+            yield None
+            self.move(3*DX[self.direction], 2*DY[self.direction])
+            yield None
+            self.move(3*DX[self.direction], 2*DY[self.direction])
 
 
 class Player(Sprite):
@@ -297,6 +332,7 @@
         self.shadows = pygame.sprite.RenderUpdates()
         self.sprites = SortedUpdates()
         self.overlays = pygame.sprite.RenderUpdates()
+        self.monsters = []
         self.use_level(Level())
 
     def use_level(self, level):
@@ -311,6 +347,9 @@
             if tile.get("player") in ('true', '1', 'yes', 'on'):
                 sprite = Player(pos)
                 self.player = sprite
+            elif tile.get('monster') in ('true', '1', 'yes', 'on'):
+                sprite = Monster(pos, SPRITE_CACHE[tile["sprite"]])
+                self.monsters.append(sprite)
             else:
                 sprite = Sprite(pos, SPRITE_CACHE[tile["sprite"]])
             self.sprites.add(sprite)
@@ -340,6 +379,7 @@
             self.player.direction = d
             if not self.level.is_blocking(x+DX[d], y+DY[d]):
                 self.player.animation = self.player.walk_animation()
+                self.player.pos = (x+DX[d], y+DY[d])
 
         if pressed(pg.K_UP):
             walk(0)
@@ -368,6 +408,8 @@
             if self.player.animation is None:
                 self.control()
                 self.player.update()
+                for monster in self.monsters:
+                    monster.ai(self.level)
             self.shadows.update()
             # Don't add shadows to dirty rectangles, as they already fit inside
             # sprite rectangles.