Editor screenshot
[erdslangetjie.git] / erdslangetjie / level.py
1 # The level object
2
3 import os
4 from data import load_image, load, filepath
5
6 WALL = '.'
7 FLOOR = ' '
8 ENTRY = 'E'
9 EXIT = 'X'
10
11
12 class Level(object):
13
14     def __init__(self, levelfile):
15         self.data = []
16         self.exit_pos = []
17         self.enter_pos = None
18         self.tiles = []
19         # Because of how kivy's coordinate system works,
20         # we reverse the lines so things match up between
21         # the file and the display (top of file == top of display)
22         for line in reversed(levelfile.readlines()):
23             self.data.append(list(line.strip('\n')))
24
25     def load_tiles(self):
26         """Load the list of tiles for the level"""
27         self.tiles = []
28         self.exit_pos = []
29         self.enter_pos = None
30         for j, line in enumerate(self.data):
31             tile_line = []
32             for i, c in enumerate(line):
33                 if c == FLOOR:
34                     tile_line.append(load_image('tiles/floor.png'))
35                 elif c == WALL:
36                     tile_line.append(self.get_wall_tile(i, j))
37                 elif c == ENTRY or c == EXIT:
38                     if c == ENTRY:
39                         if self.enter_pos:
40                             raise RuntimeError('Multiple entry points')
41                         self.enter_pos = (i, j)
42                     else:
43                         self.exit_pos.append((i, j))
44                     tile_line.append(load_image('tiles/door.png'))
45             self.tiles.append(tile_line)
46
47     def get_tiles(self):
48         return self.tiles
49
50     def get_size(self):
51         return len(self.tiles[0]), len(self.tiles)
52
53     def at_exit(self, pos):
54         return pos in self.exit_pos
55
56     def get_wall_tile(self, x, y):
57         # Is the neighbour in this direction also a wall?
58         left = right = top = bottom = False
59         if x == 0:
60             left = True
61         elif self.data[y][x - 1] == WALL:
62             left = True
63         if x == len(self.data[0]) - 1:
64             right = True
65         elif self.data[y][x + 1] == WALL:
66             right = True
67         if y == 0:
68             top = True
69         elif self.data[y - 1][x] == WALL:
70             top = True
71         if y == len(self.data) - 1:
72             bottom = True
73         elif self.data[y + 1][x] == WALL:
74             bottom = True
75         if top and bottom and left and right:
76             return load_image('tiles/cwall.png')
77         elif bottom and left and right:
78             return load_image('tiles/bottom_wall.png')
79         elif top and left and right:
80             return load_image('tiles/top_wall.png')
81         elif top and bottom and right:
82             return load_image('tiles/left_wall.png')
83         elif top and bottom and left:
84             return load_image('tiles/right_wall.png')
85         elif top and bottom:
86             return load_image('tiles/vert_wall.png')
87         elif left and right:
88             return load_image('tiles/horiz_wall.png')
89         elif left and top:
90             return load_image('tiles/corner_lt.png')
91         elif left and bottom:
92             return load_image('tiles/corner_lb.png')
93         elif right and top:
94             return load_image('tiles/corner_rt.png')
95         elif right and bottom:
96             return load_image('tiles/corner_rb.png')
97         elif top:
98             return load_image('tiles/end_top.png')
99         elif bottom:
100             return load_image('tiles/end_bottom.png')
101         elif left:
102             return load_image('tiles/end_right.png')
103         elif right:
104             return load_image('tiles/end_left.png')
105         return load_image('tiles/pillar.png')
106
107     def blocked(self, pos):
108         if pos[0] < 0:
109             return True
110         if pos[1] < 0:
111             return True
112         try:
113             tile = self.data[pos[1]][pos[0]]
114         except IndexError:
115             return True
116         if tile == '.':
117             return True
118         return False
119
120
121 class LevelList(object):
122
123     LEVELS = 'level_list'
124
125     def __init__(self):
126         self.levels = []
127         level_list = load(self.LEVELS)
128         for line in level_list:
129             line = line.strip()
130             if os.path.exists(filepath(line)):
131                 level_file = load(line)
132                 self.levels.append(Level(level_file))
133                 level_file.close()
134             else:
135                 print 'Level list includes non-existant level %s' % line
136         level_list.close()
137         self._cur_level = 0
138
139     def get_current_level(self):
140         if self._cur_level < len(self.levels):
141             return self.levels[self._cur_level]
142         else:
143             return None
144
145     def advance_to_next_level(self):
146         self._cur_level += 1
147         return self.get_current_level()
148
149     def reset(self):
150         self._cur_level = 0