tileset.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import struct
  2. from xml.etree import ElementTree
  3. import pygame
  4. class Tileset(object):
  5. TILESIZE = 16
  6. MAPSIZE = 50
  7. RIGHT = 0
  8. DOWN = 1
  9. LEFT = 2
  10. UP = 3
  11. PLAYER = 209
  12. ENEMY1 = 161
  13. def __init__(self, screen):
  14. self.screen = screen
  15. image = pygame.image.load('tileset.png').convert_alpha()
  16. self.tileset = {
  17. self.RIGHT: image,
  18. self.UP: pygame.transform.rotate(image, 90),
  19. self.LEFT: pygame.transform.rotate(image, 180),
  20. self.DOWN: pygame.transform.rotate(image, 270),
  21. }
  22. self.tile_width, self.tile_height = image.get_size()
  23. self.tile_width /= self.TILESIZE
  24. self.tile_height /= self.TILESIZE
  25. def _render(self, tile_x, tile_y, pos, direction=RIGHT):
  26. tileset = self.tileset[direction]
  27. if direction == self.RIGHT:
  28. x, y = tile_x, tile_y
  29. elif direction == self.UP:
  30. x, y = tile_y, self.tile_width - tile_x - 1
  31. elif direction == self.LEFT:
  32. x, y = self.tile_width - tile_x - 1, self.tile_height - tile_y - 1
  33. elif direction == self.DOWN:
  34. x, y = self.tile_height -tile_y - 1, tile_x
  35. x *= self.TILESIZE
  36. y *= self.TILESIZE
  37. self.screen.blit(tileset, pos, (x, y, self.TILESIZE, self.TILESIZE))
  38. def render_person(self, pos, direction):
  39. self._render(0, 13, pos, direction)
  40. def render_level(self):
  41. self.screen.blit(self.surface, (0, 0))
  42. def load_level(self): # https://bitbucket.org/r1chardj0n3s/pygame-tutorial/src/a383dd24790d/tmx.py#cl-241
  43. level_data = ElementTree.parse('level1.tmx').getroot()
  44. layers = level_data.findall('layer')
  45. if len(layers) != 3:
  46. raise Exception('expected 3 layers: floor, wall, and units')
  47. loaded = {}
  48. for layer in layers:
  49. name = layer.attrib['name']
  50. raw_data = layer.findall('data')[0].text.strip()
  51. data = raw_data.decode('base64').decode('zlib')
  52. # read as array of 4-byte ints
  53. array = list(struct.unpack('<{}i'.format(len(data)/4), data))
  54. loaded[name] = array
  55. # render level
  56. surface = pygame.Surface((800, 800))
  57. tileset = self.tileset[self.RIGHT]
  58. for layer in [loaded['floor'], loaded['wall']]:
  59. for i, tile in enumerate(layer):
  60. if tile != 0:
  61. y, x = divmod(i, self.MAPSIZE)
  62. pos = (x * self.TILESIZE, y * self.TILESIZE)
  63. tile_y, tile_x = divmod(tile - 1, self.TILESIZE) # those 1-indexing fuckers
  64. area = (tile_x * self.TILESIZE, tile_y * self.TILESIZE, self.TILESIZE, self.TILESIZE)
  65. surface.blit(tileset, pos, area)
  66. self.surface = surface
  67. # load wall
  68. collisions = set()
  69. for i, tile in enumerate(loaded['wall']):
  70. if tile != 0:
  71. y, x = divmod(i, self.MAPSIZE)
  72. collisions.add((x, y))
  73. # load units
  74. units = {
  75. self.ENEMY1: [],
  76. self.PLAYER: [],
  77. }
  78. for i, tile in enumerate(loaded['units']):
  79. if tile in units.iterkeys():
  80. y, x = divmod(i, self.MAPSIZE)
  81. units[tile].append((x, y))
  82. if len(units[self.PLAYER]) != 1:
  83. raise Exception('expected exactly 1 player tile in units layer, found ' + str(len(units[self.PLAYER])))
  84. return collisions, units