Mercurial > mhrok
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 +
