summaryrefslogtreecommitdiffstats
path: root/tileset.py
blob: e9e7d152bb99ba10867510989de1fd98da67e680 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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_alpha()
		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_person(self, pos, direction):
		self._render(0, 13, pos, direction)

	def render_level(self):
		self.screen.blit(self.surface, (0, 0))

	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

		# render level
		surface = pygame.Surface((800, 800))
		tileset = self.tileset[self.RIGHT]
		for layer in [loaded['floor'], loaded['wall']]:
			for i, tile in enumerate(layer):
				if tile != 0:
					y, x = divmod(i, self.MAPSIZE)
					pos = (x * self.TILESIZE, y * self.TILESIZE)
					tile_y, tile_x = divmod(tile - 1, self.TILESIZE) # those 1-indexing fuckers
					area = (tile_x * self.TILESIZE, tile_y * self.TILESIZE, self.TILESIZE, self.TILESIZE)
					surface.blit(tileset, pos, area)
		self.surface = surface

		# load 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