changeset 35:d95d229f6931

Further separate code into modules
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sat, 10 Mar 2012 12:04:37 +0100
parents a7c3f8601a6c
children 3d3c523edefe
files mhrok/__init__.py mhrok/display.py mhrok/level.py mhrok/mobs.py
diffstat 4 files changed, 270 insertions(+), 255 deletions(-) [+]
line wrap: on
line diff
--- a/mhrok/__init__.py	Sat Mar 10 11:53:48 2012 +0100
+++ b/mhrok/__init__.py	Sat Mar 10 12:04:37 2012 +0100
@@ -2,260 +2,12 @@
 # -*- coding: utf-8 -*-
 
 
-import random
-
 import pygame
 from pygame import locals as pg
 
 from mhrok import display
-from mhrok import sprites
-from mhrok.util import DX, DY
-
-
-class Mob(object):
-    Sprite = sprites.MobSprite
-
-    def __init__(self, (x, y)):
-        self.pos = x, y
-
-    def make_sprite(self, tiles):
-        self.sprite = self.Sprite(tiles, self.pos, self.animation)
-        shadow = sprites.Shadow(tiles, self.sprite)
-        return self.sprite, shadow, None
-
-    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]:
-                direction = None
-            else:
-                self.pos = target
-        self.sprite.direction = direction
-
-
-class Bat(Mob):
-    animation = [25, 26]
-
-
-class Chest(Mob):
-    animation = [27]
-
-    def control(self, level):
-        pass
-
-
-class Skeleton(Mob):
-    animation = [35, 35, 35, 36, 36, 36, 35, 35, 35, 37, 37, 37]
-
-
-class Teddybear(Mob):
-    animation = [30, 30, 30, 31, 31, 31, 30, 30, 30, 32, 32, 32]
-
-
-class Player(object):
-    def place(self, (x, y)):
-        self.pos = x, y
-        self.direction = 3
-        self.sprite = None
-
-    def make_sprite(self, tiles):
-        self.sprite = sprites.PlayerSprite(tiles, self.pos)
-        shadow = sprites.Shadow(tiles, self.sprite)
-        self.vision = sprites.Vision(self.sprite, 64)
-        return self.sprite, shadow, self.vision
-
-    def walk(self, level, direction):
-        self.direction = direction
-        x, y = self.pos
-        target = x + DX[direction], y + DY[direction]
-        if not level[target]:
-            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
-        return True
-
-    def control(self, level):
-        room = level.find_room(*self.pos)
-        if room:
-            self.vision.radius = 64
-            if room not in level.lit_rooms:
-                level.lit_rooms.append(room)
-                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)
-        else:
-            self.sprite.set_animation(
-                    self.sprite.stand_animation(self.direction))
-            return False
-        return True
-
-
-class SortedUpdates(pygame.sprite.RenderUpdates):
-    """Sprite group with a depth for controlling drawing order."""
-
-    def sprites(self):
-        return sorted(self.spritedict.keys(),
-                      key=lambda sprite: getattr(sprite, "depth", 0))
-
-
-class Level(object):
-    def __init__(self, pc):
-        self.pc = pc
-        self.mobs = [pc]
-        self.width = 31
-        self.height = 38
-
-        self.lit_rooms = []
-        self.map = [[0] * self.width for y in xrange(self.height)]
-
-        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([Bat, Chest, Teddybear, 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 __getitem__(self, (x, y)):
-        if self.width > x >= 0 and self.height > y >= 0:
-            return self.map[y][x]
-
-    def __setitem__(self, (x, y), value):
-        if self.width > x >= 0 and self.height > y >= 0:
-            self.map[y][x] = value
-
-    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 = 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
-
+from mhrok import mobs
+from mhrok import level
 
 
 class Game(object):
@@ -264,8 +16,8 @@
         self.clock = pygame.time.Clock()
         self.game_over = False
 
-        self.pc = Player()
-        self.level = Level(self.pc)
+        self.pc = mobs.Player()
+        self.level = level.Level(self.pc)
         self.display.render_level(self.level)
 
     def main(self):
@@ -290,6 +42,3 @@
                             continue
                         mob.sprite.direction = None
 
-
-if __name__ == '__main__':
-    Game().main()
--- a/mhrok/display.py	Sat Mar 10 11:53:48 2012 +0100
+++ b/mhrok/display.py	Sat Mar 10 12:04:37 2012 +0100
@@ -11,6 +11,14 @@
 from pygame import locals as pg
 
 
+class SortedUpdates(pygame.sprite.RenderUpdates):
+    """Sprite group with a depth for controlling drawing order."""
+
+    def sprites(self):
+        return sorted(self.spritedict.keys(),
+                      key=lambda sprite: getattr(sprite, "depth", 0))
+
+
 class Display(object):
     def __init__(self):
         pygame.display.init()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mhrok/level.py	Sat Mar 10 12:04:37 2012 +0100
@@ -0,0 +1,151 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+import random
+import pygame
+
+from mhrok import display
+from mhrok import mobs
+
+
+class Level(object):
+    def __init__(self, pc):
+        self.pc = pc
+        self.mobs = [pc]
+        self.width = 31
+        self.height = 38
+
+        self.lit_rooms = []
+        self.map = [[0] * self.width for y in xrange(self.height)]
+
+        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 __getitem__(self, (x, y)):
+        if self.width > x >= 0 and self.height > y >= 0:
+            return self.map[y][x]
+
+    def __setitem__(self, (x, y), value):
+        if self.width > x >= 0 and self.height > y >= 0:
+            self.map[y][x] = value
+
+    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
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mhrok/mobs.py	Sat Mar 10 12:04:37 2012 +0100
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+import random
+import pygame
+from pygame import locals as pg
+
+from mhrok import sprites
+from mhrok.util import DX, DY
+
+
+class Mob(object):
+    Sprite = sprites.MobSprite
+
+    def __init__(self, (x, y)):
+        self.pos = x, y
+
+    def make_sprite(self, tiles):
+        self.sprite = self.Sprite(tiles, self.pos, self.animation)
+        shadow = sprites.Shadow(tiles, self.sprite)
+        return self.sprite, shadow, None
+
+    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]:
+                direction = None
+            else:
+                self.pos = target
+        self.sprite.direction = direction
+
+
+class Bat(Mob):
+    animation = [25, 26]
+
+
+class Chest(Mob):
+    animation = [27]
+
+    def control(self, level):
+        pass
+
+
+class Skeleton(Mob):
+    animation = [35, 35, 35, 36, 36, 36, 35, 35, 35, 37, 37, 37]
+
+
+class Teddybear(Mob):
+    animation = [30, 30, 30, 31, 31, 31, 30, 30, 30, 32, 32, 32]
+
+
+class Player(object):
+    def place(self, (x, y)):
+        self.pos = x, y
+        self.direction = 3
+        self.sprite = None
+
+    def make_sprite(self, tiles):
+        self.sprite = sprites.PlayerSprite(tiles, self.pos)
+        shadow = sprites.Shadow(tiles, self.sprite)
+        self.vision = sprites.Vision(self.sprite, 64)
+        return self.sprite, shadow, self.vision
+
+    def walk(self, level, direction):
+        self.direction = direction
+        x, y = self.pos
+        target = x + DX[direction], y + DY[direction]
+        if not level[target]:
+            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
+        return True
+
+    def control(self, level):
+        room = level.find_room(*self.pos)
+        if room:
+            self.vision.radius = 64
+            if room not in level.lit_rooms:
+                level.lit_rooms.append(room)
+                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)
+        else:
+            self.sprite.set_animation(
+                    self.sprite.stand_animation(self.direction))
+            return False
+        return True