changeset 38:b637ee420b8a

Move walking logic into level
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sat, 10 Mar 2012 12:31:08 +0100
parents 18646f021d62
children 2475e658d13f
files mhrok/__init__.py mhrok/level.py mhrok/mobs.py mhrok/rooms_level.py
diffstat 4 files changed, 114 insertions(+), 148 deletions(-) [+]
line wrap: on
line diff
--- a/mhrok/__init__.py	Sat Mar 10 12:12:15 2012 +0100
+++ b/mhrok/__init__.py	Sat Mar 10 12:31:08 2012 +0100
@@ -7,7 +7,7 @@
 
 from mhrok import display
 from mhrok import mobs
-from mhrok import level
+from mhrok import rooms_level
 
 
 class Game(object):
@@ -17,7 +17,7 @@
         self.game_over = False
 
         self.pc = mobs.Player()
-        self.level = level.Level(self.pc)
+        self.level = rooms_level.Level(self.pc)
         self.display.render_level(self.level)
 
     def main(self):
--- a/mhrok/level.py	Sat Mar 10 12:12:15 2012 +0100
+++ b/mhrok/level.py	Sat Mar 10 12:31:08 2012 +0100
@@ -2,11 +2,22 @@
 # -*- coding: utf-8 -*-
 
 
-import random
-import pygame
+from mhrok.util import DX, DY
+
+
+class Error(Exception):
+    pass
 
-from mhrok import display
-from mhrok import mobs
+class Blocked(Error):
+    pass
+
+class BlockedWall(Blocked):
+    pass
+
+class BlockedMob(Blocked):
+    def __init__(self, mob):
+        self.mob = mob
+
 
 class BaseLevel(object):
     def __init__(self, pc):
@@ -18,6 +29,10 @@
         self.lit_rooms = []
         self.map = [[0] * self.width for y in xrange(self.height)]
 
+        self.Blocked = Blocked
+        self.BlockedWall = BlockedWall
+        self.BlockedMob = BlockedMob
+
     def __getitem__(self, (x, y)):
         if self.width > x >= 0 and self.height > y >= 0:
             return self.map[y][x]
@@ -26,130 +41,14 @@
         if self.width > x >= 0 and self.height > y >= 0:
             self.map[y][x] = value
 
-
-class Level(BaseLevel):
-    def __init__(self, pc):
-        super(Level, self).__init__(pc)
-
-        areas = [
-            ((0, 0), (9, 11)), ((11, 0), (9, 11)), ((22, 0), (9, 11)),
-            ((0, 13), (9, 11)), ((11, 13), (9, 11)), ((22, 13), (9, 11)),
-            ((0, 26), (9, 11)), ((11, 26), (9, 11)), ((22, 26), (9, 11)),
-        ]
-
-        rooms = []
-        r = random.randint
-        for (x, y), (w, h) in areas:
-            width = r(1, w/2) * 2
-            height = r(1, h/2) * 2
-            x_offset = r(0, (w - width)/2) * 2
-            y_offset = r(0, (h - height)/2) * 2
-            rooms.append(((x + x_offset, y + y_offset), (width, height)))
-
-        random.shuffle(rooms)
-
-        for room, next_room in zip(rooms, rooms[1:]):
-            (x, y), (w, h) = room
-            (nx, ny), (nw, nh) = next_room
-            x1 = nx + r(0, nw/2) * 2
-            y1 = ny + r(0, nh/2) * 2
-            x2 = x + r(0, w/2) * 2
-            y2 = y + r(0, h/2) * 2
-            self._path((x1, y1), (x2, y2), 2)
-
-        for room in rooms:
-            (x, y), (w, h) = room
-            self._fill((x, y), (w + 1, h + 1), 1)
-            for i in xrange(r(0, 2)):
-                self[r(x, x+w), r(y, y+h)] = 3
-            for i in xrange(r(1, 3)):
-                self[r(x, x+w), r(y, y+h)] = 4
-            for i in xrange(r(1, 4)):
-                MobClass = random.choice([mobs.Bat, mobs.Chest, mobs.Teddybear, mobs.Skeleton])
-                self.mobs.append(MobClass((r(x, x + w), r(y, y + h))))
-        self[r(x, x+w), r(y, y+h)] = 5
-
-        (x, y), (w, h) = random.choice(rooms)
-        self.pc.place((r(x, x+w), r(y, y+h)))
-        self.rooms = rooms
+    def walk(self, mob, direction):
+        x, y = mob.pos
+        target = x + DX[direction], y + DY[direction]
+        for m in self.mobs:
+            if m.pos == target:
+                raise self.BlockedMob(m)
+        if not self[target]:
+            raise self.BlockedWall()
+        mob.pos = target
 
 
-    def _fill(self, (sx, sy), (width, height), fill):
-        for y in xrange(sy, sy + height):
-            for x in xrange(sx, sx + width):
-                self[x, y] = fill
-
-    def _path(self, (sx, sy), (ex, ey), fill):
-        for x in xrange(sx, ex, 1 if sx < ex else -1):
-            if self[x, sy]:
-                return
-            self[x, sy] = fill
-        for y in xrange(sy, ey, 1 if sy < ey else -1):
-            if self[ex, y]:
-                return
-            self[ex, y] = fill
-
-    def find_room(self, x, y):
-        for room in self.rooms:
-            (rx, ry), (rw, rh) = room
-            if rx <= x <= rx + rw and ry <= y <= ry + rh:
-                return room
-
-    def render_background(self, tiles):
-        background = pygame.Surface((self.width * 20 + 20, self.height * 12 + 20))
-        background.fill((16, 8, 0))
-        blood = tiles[21].copy()
-        blood.set_alpha(220)
-        blood2 = tiles[22].copy()
-        blood2.set_alpha(220)
-        for y, row in enumerate(self.map):
-            for x, square in enumerate(row):
-                pos = x * 20 + 4, y * 12
-                border = 0
-                if square == 1:
-                    background.blit(tiles[23], pos)
-                    border = 4
-                elif square == 2:
-                    background.blit(tiles[33], pos)
-                    border = 24
-                elif square == 3:
-                    background.blit(tiles[23], pos)
-                    background.blit(blood, pos)
-                    border = 4
-                elif square == 4:
-                    background.blit(tiles[23], pos)
-                    background.blit(blood2, pos)
-                    border = 4
-                elif square == 5:
-                    background.blit(tiles[38], pos)
-                    border = 4
-                elif square < 0:
-                    background.blit(tiles[39 - square], pos)
-                    border = 24
-                if border:
-                    if not self[x - 1, y]:
-                        background.blit(tiles[5 + border], pos)
-                    if not self[x + 1, y]:
-                        background.blit(tiles[15 + border], pos)
-                    if not self[x, y - 1]:
-                        background.blit(tiles[border], pos)
-                    if not self[x, y + 1]:
-                        background.blit(tiles[10 + border], pos)
-
-        return background
-
-    def render_sprites(self, tiles):
-        sprites = display.SortedUpdates()
-        shadows = pygame.sprite.RenderUpdates()
-        visions = pygame.sprite.LayeredDirty()
-        for mob in self.mobs:
-            sprite, shadow, vision = mob.make_sprite(tiles)
-            if sprite:
-                sprites.add(sprite)
-            if shadow:
-                shadows.add(shadow)
-            if vision:
-                visions.add(vision)
-        return sprites, shadows, visions
-
-
--- a/mhrok/mobs.py	Sat Mar 10 12:12:15 2012 +0100
+++ b/mhrok/mobs.py	Sat Mar 10 12:31:08 2012 +0100
@@ -9,7 +9,6 @@
 from mhrok import sprites
 from mhrok.util import DX, DY
 
-
 class Mob(object):
     Sprite = sprites.MobSprite
 
@@ -24,16 +23,10 @@
     def control(self, level):
         direction = random.choice([None, 0, 1, 2, 3])
         if direction is not None:
-            x, y = self.pos
-            target = x + DX[direction], y + DY[direction]
-            for mob in level.mobs:
-                if mob.pos == target:
-                    self.sprite.direction = None
-                    return
-            if not level[target]:
+            try:
+                level.walk(self, direction)
+            except level.Blocked:
                 direction = None
-            else:
-                self.pos = target
         self.sprite.direction = direction
 
 
@@ -70,15 +63,12 @@
 
     def walk(self, level, direction):
         self.direction = direction
-        x, y = self.pos
-        target = x + DX[direction], y + DY[direction]
-        if not level[target]:
+        try:
+            level.walk(self, direction)
+        except level.Blocked:
             return False
-        for mob in level.mobs:
-            if mob.pos == target:
-                return False
         self.sprite.set_animation(self.sprite.walk_animation(direction))
-        self.pos = target
+        print self.pos
         return True
 
     def control(self, level):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mhrok/rooms_level.py	Sat Mar 10 12:31:08 2012 +0100
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import random
+
+from mhrok import mobs
+from mhrok import level
+
+
+class Level(level.BaseLevel):
+    def __init__(self, pc):
+        super(Level, self).__init__(pc)
+
+        areas = [
+            ((0, 0), (9, 11)), ((11, 0), (9, 11)), ((22, 0), (9, 11)),
+            ((0, 13), (9, 11)), ((11, 13), (9, 11)), ((22, 13), (9, 11)),
+            ((0, 26), (9, 11)), ((11, 26), (9, 11)), ((22, 26), (9, 11)),
+        ]
+
+        rooms = []
+        r = random.randint
+        for (x, y), (w, h) in areas:
+            width = r(1, w/2) * 2
+            height = r(1, h/2) * 2
+            x_offset = r(0, (w - width)/2) * 2
+            y_offset = r(0, (h - height)/2) * 2
+            rooms.append(((x + x_offset, y + y_offset), (width, height)))
+
+        random.shuffle(rooms)
+
+        for room, next_room in zip(rooms, rooms[1:]):
+            (x, y), (w, h) = room
+            (nx, ny), (nw, nh) = next_room
+            x1 = nx + r(0, nw/2) * 2
+            y1 = ny + r(0, nh/2) * 2
+            x2 = x + r(0, w/2) * 2
+            y2 = y + r(0, h/2) * 2
+            self._path((x1, y1), (x2, y2), 2)
+
+        for room in rooms:
+            (x, y), (w, h) = room
+            self._fill((x, y), (w + 1, h + 1), 1)
+            for i in xrange(r(0, 2)):
+                self[r(x, x+w), r(y, y+h)] = 3
+            for i in xrange(r(1, 3)):
+                self[r(x, x+w), r(y, y+h)] = 4
+            for i in xrange(r(1, 4)):
+                MobClass = random.choice([mobs.Bat, mobs.Chest, mobs.Teddybear, mobs.Skeleton])
+                self.mobs.append(MobClass((r(x, x + w), r(y, y + h))))
+        self[r(x, x+w), r(y, y+h)] = 5
+
+        (x, y), (w, h) = random.choice(rooms)
+        self.pc.place((r(x, x+w), r(y, y+h)))
+        self.rooms = rooms
+
+
+    def _fill(self, (sx, sy), (width, height), fill):
+        for y in xrange(sy, sy + height):
+            for x in xrange(sx, sx + width):
+                self[x, y] = fill
+
+    def _path(self, (sx, sy), (ex, ey), fill):
+        for x in xrange(sx, ex, 1 if sx < ex else -1):
+            if self[x, sy]:
+                return
+            self[x, sy] = fill
+        for y in xrange(sy, ey, 1 if sy < ey else -1):
+            if self[ex, y]:
+                return
+            self[ex, y] = fill
+
+    def find_room(self, x, y):
+        for room in self.rooms:
+            (rx, ry), (rw, rh) = room
+            if rx <= x <= rx + rw and ry <= y <= ry + rh:
+                return room
+