import struct from xml.etree import ElementTree import pygame class Tileset(object): TILESIZE = 16 MAPSIZE = 50 RIGHT = 0 DOWN = 1 LEFT = 2 UP = 3 PLAYER = 209 ENEMY1 = 161 def __init__(self, screen): self.screen = screen image = pygame.image.load('tileset.png').convert() self.tileset = { self.RIGHT: image, self.UP: pygame.transform.rotate(image, 90), self.LEFT: pygame.transform.rotate(image, 180), self.DOWN: pygame.transform.rotate(image, 270), } self.tile_width, self.tile_height = image.get_size() self.tile_width /= self.TILESIZE self.tile_height /= self.TILESIZE def _render(self, tile_x, tile_y, pos, direction=RIGHT): tileset = self.tileset[direction] if direction == self.RIGHT: x, y = tile_x, tile_y elif direction == self.UP: x, y = tile_y, self.tile_width - tile_x - 1 elif direction == self.LEFT: x, y = self.tile_width - tile_x - 1, self.tile_height - tile_y - 1 elif direction == self.DOWN: x, y = self.tile_height -tile_y - 1, tile_x x *= self.TILESIZE y *= self.TILESIZE self.screen.blit(tileset, pos, (x, y, self.TILESIZE, self.TILESIZE)) def _render_layer(self, layer): for i, tile in enumerate(layer): y, x = divmod(i, self.MAPSIZE) x *= self.TILESIZE y *= self.TILESIZE if tile != 0: tile_y, tile_x = divmod(tile - 1, self.TILESIZE) # those 1-indexing fuckers self._render(tile_x, tile_y, (x, y)) def render_person(self, pos, direction): self._render(0, 13, pos, direction) def render_level(self): self._render_layer(self.floor) self._render_layer(self.walls) def load_level(self): # https://bitbucket.org/r1chardj0n3s/pygame-tutorial/src/a383dd24790d/tmx.py#cl-241 level_data = ElementTree.parse('level1.tmx').getroot() layers = level_data.findall('layer') if len(layers) != 3: raise Exception('expected 3 layers: floor, wall, and units') loaded = {} for layer in layers: name = layer.attrib['name'] raw_data = layer.findall('data')[0].text.strip() data = raw_data.decode('base64').decode('zlib') # read as array of 4-byte ints array = list(struct.unpack('<{}i'.format(len(data)/4), data)) loaded[name] = array # load floor self.floor = loaded['floor'] # load wall self.walls = loaded['wall'] collisions = set() for i, tile in enumerate(loaded['wall']): if tile != 0: y, x = divmod(i, self.MAPSIZE) collisions.add((x, y)) # load units units = { self.ENEMY1: [], self.PLAYER: [], } for i, tile in enumerate(loaded['units']): if tile in units.iterkeys(): y, x = divmod(i, self.MAPSIZE) units[tile].append((x, y)) if len(units[self.PLAYER]) != 1: raise Exception('expected exactly 1 player tile in units layer, found ' + str(len(units[self.PLAYER]))) return collisions, units