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