FLOOR = ' '
ENTRY = 'E'
EXIT = 'X'
+GATE = 'G'
+BUTTON = 'B'
class Level(object):
def __init__(self, levelfile):
- self.data = []
+ self._data = []
self.exit_pos = []
self.enter_pos = None
- self.tiles = []
+ self._tiles = []
+ self._changed = []
+ self._gates = {}
+ self._buttons = {}
# Because of how kivy's coordinate system works,
# we reverse the lines so things match up between
# the file and the display (top of file == top of display)
for line in reversed(levelfile.readlines()):
- self.data.append(list(line.strip('\n')))
+ self._data.append(list(line.strip('\n')))
def load_tiles(self):
"""Load the list of tiles for the level"""
- self.tiles = []
+ self._tiles = []
+ self._gates = {}
+ self._buttons = {}
self.exit_pos = []
+ self._changed = []
self.enter_pos = None
- for j, line in enumerate(self.data):
+ for j, line in enumerate(self._data):
tile_line = []
for i, c in enumerate(line):
if c == FLOOR:
tile_line.append(load_image('tiles/floor.png'))
elif c == WALL:
- tile_line.append(self.get_wall_tile(i, j))
- elif c == ENTRY or c == EXIT:
- if c == ENTRY:
- if self.enter_pos:
- raise RuntimeError('Multiple entry points')
- self.enter_pos = (i, j)
- else:
- self.exit_pos.append((i, j))
+ tile_line.append(self._get_wall_tile(i, j))
+ elif c == ENTRY:
+ if self.enter_pos:
+ raise RuntimeError('Multiple entry points')
+ self.enter_pos = (i, j)
+ tile_line.append(load_image('tiles/entry.png'))
+ elif c == EXIT:
+ self.exit_pos.append((i, j))
tile_line.append(load_image('tiles/door.png'))
- self.tiles.append(tile_line)
+ elif c == GATE:
+ tile_line.append('tiles/gate_down.png')
+ self._gates[(i, j)] = -1 # down
+ elif c == BUTTON:
+ tile_line.append('tiles/button.png')
+ self._buttons[(i, j)] = 'active'
+ self._tiles.append(tile_line)
def get_tiles(self):
- return self.tiles
+ return self._tiles
+
+ def get_single_tile(self, pos):
+ return self._tiles[pos[1]][pos[0]]
def get_size(self):
- return len(self.tiles[0]), len(self.tiles)
+ return len(self._tiles[0]), len(self._tiles)
def at_exit(self, pos):
return pos in self.exit_pos
- def get_wall_tile(self, x, y):
+ def _get_wall_tile(self, x, y):
# Is the neighbour in this direction also a wall?
left = right = top = bottom = False
if x == 0:
left = True
- elif self.data[y][x - 1] == WALL:
+ elif self._data[y][x - 1] == WALL:
left = True
- if x == len(self.data[0]) - 1:
+ if x == len(self._data[0]) - 1:
right = True
- elif self.data[y][x + 1] == WALL:
+ elif self._data[y][x + 1] == WALL:
right = True
if y == 0:
top = True
- elif self.data[y - 1][x] == WALL:
+ elif self._data[y - 1][x] == WALL:
top = True
- if y == len(self.data) - 1:
+ if y == len(self._data) - 1:
bottom = True
- elif self.data[y + 1][x] == WALL:
+ elif self._data[y + 1][x] == WALL:
bottom = True
if top and bottom and left and right:
return load_image('tiles/cwall.png')
if pos[1] < 0:
return True
try:
- tile = self.data[pos[1]][pos[0]]
+ tile = self._data[pos[1]][pos[0]]
except IndexError:
return True
- if tile == '.':
+ if tile == WALL or tile == ENTRY:
return True
+ if tile == GATE:
+ if self._gates[pos] != 'down':
+ return True
return False
+ def is_gate(self, pos):
+ return self._data[pos[1]][pos[0]] == GATE
+
+ def is_button(self, pos):
+ return self._data[pos[1]][pos[0]] == BUTTON
+
+ def trigger_button(self, pos):
+ if not self.is_button(pos):
+ return False
+ if not self._buttons[pos] == 'active':
+ return False
+ # Find the closest gate down gate and trigger it
+ gate_pos = pos
+
+ self._changed.append((pos, self.get_single_tile(pos)))
+ self._changed.append((gate_pos, self.get_single_tile(pos)))
+
+ def damage_gate(self, pos):
+ if not self.is_gate(pos):
+ return False
+ if self._gates[pos] == -1 or self._gates[pos] == 0:
+ return False
+ self._gates[pos] = self._gates[pos] - 1
+ self._fix_gate_tile(pos)
+ self._changed.append((pos, self.get_single_tile(pos)))
+ return True
+
+ def get_changed_tiles(self):
+ ret = self._changed[:]
+ self._changed = []
+ return ret
+
class LevelList(object):