Mercurial > skaapsteker
view skaapsteker/level.py @ 572:11d8b6b407e5 pyweek12 0.1
Turn off debug
author | Stefano Rivera <stefano@rivera.za.net> |
---|---|
date | Sun, 10 Apr 2011 02:53:40 +0200 |
parents | 4de4f94c326d |
children | a91b2e4400a5 |
line wrap: on
line source
import json from pygame import Rect, Surface, Color, mixer from pygame.sprite import LayeredUpdates from . import data from .constants import SCREEN, Layers from .sprites.base import TILE_SIZE, find_sprite, Geography from .widgets.text import Text class TileSet(object): def __init__(self, dirname): self.dirname = dirname self.tile_factories = { '.': lambda pos: None, '?': lambda pos: None, # Object placement helper '-': self.tile_factory('floor.png', True), 'X': self.tile_factory('wall.png', True, True), '<': self.tile_factory('floor-end-l.png', True), '>': self.tile_factory('floor-end-r.png', True), '=': self.tile_factory('floor-start-l.png', True), '+': self.tile_factory('floor-start-r.png', True), '(': self.tile_factory('wall-end-l.png', True, True), ')': self.tile_factory('wall-end-r.png', True, True), 'q': self.tile_factory('wall-end-tr.png', True, True), 'd': self.tile_factory('wall-end-br.png', True, True), 'p': self.tile_factory('wall-end-tl.png', True, True), 'b': self.tile_factory('wall-end-bl.png', True, True), '{': self.tile_factory('arch-l.png'), '}': self.tile_factory('arch-r.png'), '|': self.tile_factory('bamboo.png', layer=Layers.BACKGROUND, dirname='common'), 'h': self.tile_factory('hanging-lantern.png', layer=Layers.IN_FRONT, dirname='common'), 's': self.tile_factory('standing-lantern.png', layer=Layers.IN_FRONT, dirname='common'), '!': self.tile_factory('dangly-bits.png', layer=Layers.IN_FRONT, dirname='common'), 'k': self.tile_factory('skaapsteker.png', layer=Layers.SKAAPSTEKER, dirname='skaapsteker'), } def get_tile(self, tilechar, pos): return self.tile_factories[tilechar](pos) def tile_factory(self, image_name, floor=False, block=False, layer=Layers.BACKGROUND, dirname=None): if not dirname: dirname = self.dirname image = data.load_image('tiles/' + dirname + '/' + image_name) def _tilefac(pos): tile = Geography(pos, image) tile.block = block tile.floor = floor tile._layer = layer if not (tile.block or tile.floor): tile.collides_with = set() return tile return _tilefac class Level(object): def __init__(self, leveldef, soundsystem): self.name = leveldef self.level_data = json.loads(data.load('levels/' + leveldef + '.json').read()) self.sprites = LayeredUpdates() self._soundsystem = soundsystem self.build_tiles() self.build_backgrounds() self.setup_enemies() self.setup_doorways() self._background_music = None if 'music' in self.level_data: # soundsystem will call data.filepath self._background_music = 'music/' + self.level_data['music'].get('track', '') self._background_volume = self.level_data['music'].get('volume', 1.0) def build_backgrounds(self): self.backgrounds = [] for i, background in enumerate(self.level_data['backgrounds']): image = data.load_image('backgrounds/' + background) clip_rect = Rect((0, 0), self.pixel_size) if i == 0: clip_rect = Rect((0, 0), (int(self.pixel_size[0] * 0.75), int(self.pixel_size[1] * 0.75))) clip_rect = clip_rect.clip(image.get_rect()) clip_rect = clip_rect.union(Rect((0, 0), SCREEN)) clip_rect.midbottom = image.get_rect().midbottom image = image.subsurface(clip_rect) self.backgrounds.append(image) def enter(self): if self._background_music: self._soundsystem.play_background_music(self._background_music, self._background_volume) def leave(self): pass def build_tiles(self): self.tileset = TileSet(self.level_data['tileset']) self.tiles = LayeredUpdates() tile_data = self.level_data['tiles'] self.tile_size = (len(tile_data[0]), len(tile_data)) self.pixel_size = (self.tile_size[0] * TILE_SIZE[0], self.tile_size[1] * TILE_SIZE[1]) for y, row in enumerate(tile_data): for x, char in enumerate(row): tile = self.tileset.get_tile(char, (x, y)) if tile: self.tiles.add(tile) self.sprites.add(tile) def setup_enemies(self): self.enemies = LayeredUpdates() for enemy_def in self.level_data['enemies']: enemy = find_sprite(enemy_def, 'enemies') self.enemies.add(enemy) self.sprites.add(enemy) def setup_doorways(self): self.doorways = {} for door_name, door_def in self.level_data['doorways'].items(): doorway = find_sprite(door_def, 'base') self.doorways[door_name] = doorway self.sprites.add(doorway) def get_surface(self): return Surface(self.pixel_size) def get_background_pos(self, background, viewport): vp_x, vp_y = viewport.size bg_scalable = background.get_rect().inflate(-vp_x, -vp_y).size lev_scalable = Rect((0, 0), self.pixel_size).inflate(-vp_x, -vp_y).size return ((viewport.left * bg_scalable[0]) / lev_scalable[0], (viewport.top * bg_scalable[1]) / lev_scalable[1]) def draw_background(self, surface): clip_rect = surface.get_clip() for background in self.backgrounds: bg_pos = self.get_background_pos(background, clip_rect) surface.blit(background, clip_rect.topleft, Rect(bg_pos, clip_rect.size)) def draw_tiles(self, surface): self.tiles.draw(surface) def draw(self, surface): self.draw_background(surface) class DebugLevel(Level): """Used by level-editor""" def build_tiles(self): super(DebugLevel, self).build_tiles() tile_data = self.level_data['tiles'] for y, row in enumerate(tile_data): for x, char in enumerate(row): if char == '?': self.check_debug_tile(x, y) def check_debug_tile(self, x, y): objects = [] objects += self.level_data.get('enemies', []) objects += self.level_data.get('sprites', []) doorways = self.level_data.get('doorways', {}) objects += doorways.values() for object_ in objects: if [x, y] == object_['pos']: break else: tile = self.get_debug_tile(x, y) print "Debug tile at (%i, %i)" % (x, y) self.tiles.add(tile) self.sprites.add(tile) def get_debug_tile(self, x, y): surface = Surface((64, 64)) surface.fill(Color('black')) text = Text("? Tile at\n(%i, %i)" % (x, y), (2, 2), size=14, color='white') text.draw(surface) return Geography((x, y), surface.convert_alpha())