data/states/town.py (view raw)
1__author__ = 'justinarmstrong'
2
3import os
4import pygame as pg
5from .. import setup, tools, collision
6from .. import constants as c
7from .. components.player import Player
8
9class Town(tools._State):
10 def __init__(self):
11 super(Town, self).__init__()
12
13
14 def startup(self, current_time, persist):
15 """Called when the State object is created"""
16 self.persist = persist
17 self.current_time = current_time
18 self.get_image = setup.tools.get_image
19 self.town_map_dict = self.create_town_sprite_sheet_dict()
20 self.town_map = self.create_town_map()
21 self.blockers = self.create_blockers()
22 self.viewport = self.create_viewport()
23 self.level_surface = self.create_level_surface()
24 self.level_rect = self.level_surface.get_rect()
25 self.player = Player()
26 self.start_positions = self.set_sprite_positions()
27 self.collision_handler = collision.CollisionHandler(self.player,
28 self.blockers)
29
30
31 def create_town_sprite_sheet_dict(self):
32 """Create a dictionary of sprite sheet tiles"""
33 tile_dict = {}
34 tileset1 = setup.GFX['tileset1']
35 tileset2 = setup.GFX['tileset2']
36 tileset3 = setup.GFX['tileset3']
37 sword = setup.GFX['sword']
38 shield = setup.GFX['shield']
39 potion = setup.GFX['potion']
40 gem = setup.GFX['gem']
41
42 tile_dict['pavement'] = self.get_tile(32, 48, tileset2)
43 tile_dict['house wall'] = self.get_tile(64, 48, tileset2)
44 tile_dict['house roof'] = self.get_tile(0, 144, tileset2)
45 tile_dict['house door'] = self.get_tile(48, 64, tileset2)
46 tile_dict['tree'] = self.get_tile(80, 48, tileset1, 16, 32)
47 tile_dict['well'] = self.get_tile(96, 50, tileset1, 16, 32)
48 tile_dict['moat'] = self.get_tile(16, 16, tileset2)
49 tile_dict['fence'] = self.get_tile(48, 64, tileset1)
50 tile_dict['grass'] = self.get_tile(0, 16, tileset1)
51 tile_dict['sword'] = self.get_tile(0, 0, sword, 32, 32)
52 tile_dict['shield'] = self.get_tile(0, 0, shield, 32, 32)
53 tile_dict['potion'] = self.get_tile(0, 0, potion, 32, 32)
54 tile_dict['gem'] = self.get_tile(0, 0, gem, 32, 32)
55 tile_dict['castle bridge'] = self.get_tile(48, 27, tileset1, 16, 32 )
56 tile_dict['flower1'] = self.get_tile(64, 64, tileset2)
57 tile_dict['flower2'] = self.get_tile(80, 64, tileset2)
58 tile_dict['horiz castle wall'] = self.get_tile(32, 0, tileset3, 48, 32)
59 tile_dict['vert castle wall'] = self.get_tile(0, 16, tileset3)
60 tile_dict['castle tower'] = self.get_tile(116, 16, tileset1, 48, 64)
61 tile_dict['main castle roof'] = self.get_tile(0, 0, tileset1, 160, 16)
62 tile_dict['left castle roof piece'] = self.get_tile(0, 0, tileset1, 48, 16)
63 tile_dict['right castle roof piece'] = self.get_tile(112, 0, tileset1, 48, 16)
64 tile_dict['castle side'] = self.get_tile(0, 72, tileset3)
65 tile_dict['castle door'] = self.get_tile(32, 64, tileset2, 16, 16, 4)
66
67 return tile_dict
68
69
70 def get_tile(self, x, y, tileset, width=16, height=16, scale=1):
71 """Gets the surface and rect for a tile"""
72 surface = self.get_image(self, x, y, width, height, tileset)
73 surface = pg.transform.scale(surface, (width*scale, height*scale))
74 rect = surface.get_rect()
75
76 tile_dict = {'surface': surface,
77 'rect': rect}
78
79 return tile_dict
80
81
82 def create_town_map(self):
83 """Blits the different layers of the map onto one surface"""
84 map = self.create_background()
85 map = self.create_map_layer1(map)
86 map = self.create_map_layer2(map)
87 map = self.scale_map(map)
88 map = self.create_map_layer3(map)
89
90 return map
91
92
93 def create_background(self):
94 """Creates the background surface that the rest of
95 the town map will be blitted on"""
96 size = (25*16, 50*16)
97 surface = pg.Surface(size)
98 grass_tile = self.get_image(self, 0, 0, 16, 16, setup.GFX['tileset2'])
99 grass_rect = grass_tile.get_rect()
100
101 for row in range(50):
102 for column in range(25):
103 grass_rect.y = row * 16
104 grass_rect.x = column * 16
105 surface.blit(grass_tile, grass_rect)
106
107 surface_rect = surface.get_rect()
108
109 background_dict = {'surface': surface,
110 'rect': surface_rect}
111
112 return background_dict
113
114
115 def create_map_layer1(self, map):
116 """Creates the town from a tile map and creates a
117 surface on top of the background"""
118 tile_map = open(os.path.join('data', 'states', 'town_map.txt'), 'r')
119
120 for row, line in enumerate(tile_map):
121 for column, letter in enumerate(line):
122 if letter == '1':
123 tile = self.town_map_dict['pavement']
124 self.blit_tile_to_map(tile, row, column, map)
125
126 elif letter == '2':
127 tile = self.town_map_dict['house wall']
128 self.blit_tile_to_map(tile, row, column, map)
129
130 elif letter == '3':
131 tile = self.town_map_dict['house roof']
132 self.blit_tile_to_map(tile, row, column, map)
133
134 elif letter == 'T':
135 tile = self.town_map_dict['tree']
136 self.blit_tile_to_map(tile, row, column, map)
137
138 elif letter == 'W':
139 tile = self.town_map_dict['well']
140 self.blit_tile_to_map(tile, row, column, map)
141
142 elif letter == 'M':
143 tile = self.town_map_dict['moat']
144 self.blit_tile_to_map(tile, row, column, map)
145
146 elif letter == 'G':
147 tile = self.town_map_dict['grass']
148 self.blit_tile_to_map(tile, row, column, map)
149
150 elif letter == 'B':
151 tile = self.town_map_dict['castle bridge']
152 self.blit_tile_to_map(tile, row, column, map)
153
154 elif letter == 'C':
155 tile = self.town_map_dict['horiz castle wall']
156 self.blit_tile_to_map(tile, row, column, map)
157
158 elif letter == 'V':
159 tile = self.town_map_dict['vert castle wall']
160 self.blit_tile_to_map(tile, row, column, map)
161
162 elif letter == 'S':
163 tile = self.town_map_dict['castle side']
164 self.blit_tile_to_map(tile, row, column, map)
165
166
167 tile_map.close()
168
169 return map
170
171
172 def create_map_layer2(self, map):
173 """Creates doors and other items on top of the rest of the map"""
174 tile_map = open(os.path.join('data', 'states', 'town_layer2.txt'), 'r')
175
176 for row, line in enumerate(tile_map):
177 for column, letter in enumerate(line):
178 if letter == 'D':
179 tile = self.town_map_dict['house door']
180 self.blit_tile_to_map(tile, row, column, map)
181 elif letter == 'F':
182 tile = self.town_map_dict['fence']
183 self.blit_tile_to_map(tile, row, column, map)
184 elif letter == '$':
185 tile = self.town_map_dict['flower1']
186 self.blit_tile_to_map(tile, row, column, map)
187 elif letter == '*':
188 tile = self.town_map_dict['flower2']
189 self.blit_tile_to_map(tile, row, column, map)
190 elif letter == 'T':
191 tile = self.town_map_dict['castle tower']
192 self.blit_tile_to_map(tile, row, column, map)
193 elif letter == 'W':
194 tile = self.town_map_dict['vert castle wall']
195 self.blit_tile_to_map(tile, row, column, map)
196 elif letter == 'M':
197 tile = self.town_map_dict['main castle roof']
198 self.blit_tile_to_map(tile, row, column, map)
199 elif letter == 'L':
200 tile = self.town_map_dict['left castle roof piece']
201 self.blit_tile_to_map(tile, row, column, map)
202 elif letter == 'R':
203 tile = self.town_map_dict['right castle roof piece']
204 self.blit_tile_to_map(tile, row, column, map)
205 elif letter == '#':
206 tile = self.town_map_dict['tree']
207 self.blit_tile_to_map(tile, row, column, map)
208 elif letter == 'O':
209 tile = self.town_map_dict['castle door']
210 self.blit_tile_to_map(tile, row, column, map)
211
212 tile_map.close()
213
214 return map
215
216
217 def scale_map(self, map):
218 """Double resolution of map to 32x32"""
219 map['surface'] = pg.transform.scale2x(map['surface'])
220 map['rect'] = map['surface'].get_rect()
221
222 return map
223
224
225 def create_map_layer3(self, map):
226 """Layers for images that are already 32x32"""
227 tile_map = open(os.path.join('data', 'states', 'town_layer3.txt'), 'r')
228
229 for row, line in enumerate(tile_map):
230 for column, letter in enumerate(line):
231 if letter == 'W':
232 tile = self.town_map_dict['sword']
233 self.blit_tile_to_map(tile, row, column, map, 32)
234 elif letter == 'A':
235 tile = self.town_map_dict['shield']
236 self.blit_tile_to_map(tile, row, column, map, 32)
237 elif letter == 'P':
238 tile = self.town_map_dict['potion']
239 self.blit_tile_to_map(tile, row, column, map, 32)
240 elif letter == 'M':
241 tile = self.town_map_dict['gem']
242 self.blit_tile_to_map(tile, row, column, map, 32)
243
244 tile_map.close()
245
246 return map
247
248
249
250 def blit_tile_to_map(self, tile, row, column, map, side_length=16):
251 """Places tile to map"""
252 tile['rect'].x = column * side_length
253 tile['rect'].y = row * side_length
254
255 map['surface'].blit(tile['surface'], tile['rect'])
256
257
258 def create_blockers(self):
259 """Creates invisible rect objects that will prevent the player from
260 walking into trees, buildings and other solid objects"""
261 tile_map = open(os.path.join('data', 'states', 'town_blocker_layer.txt'), 'r')
262 blocker_list = []
263
264 for row, line in enumerate(tile_map):
265 for column, letter in enumerate(line):
266 if letter == 'B':
267 blocker_list.append(pg.Rect(column*32, row*32, 32, 32))
268
269 tile_map.close()
270
271 return blocker_list
272
273
274 def create_viewport(self):
275 """Create the viewport to view the level through"""
276 return setup.SCREEN.get_rect(bottom=self.town_map['rect'].bottom)
277
278
279 def create_level_surface(self):
280 """Creates the surface all images are blitted to"""
281 width = self.town_map['rect'].width
282 height = self.town_map['rect'].height
283
284 return pg.Surface((width, height)).convert()
285
286
287 def set_sprite_positions(self):
288 """Set the start positions for all the sprites in the level"""
289 tile_map = open(os.path.join('data', 'states', 'sprite_start_pos.txt'), 'r')
290 dict = {}
291
292 for row, line in enumerate(tile_map):
293 for column, letter in enumerate(line):
294 if letter == 'P':
295 dict['player'] = pg.Rect(column*32, row*32, 32, 32)
296
297 self.player.rect = dict['player']
298
299 return dict
300
301
302 def update(self, surface, keys, current_time):
303 """Updates state"""
304 self.keys = keys
305 self.current_time = current_time
306 self.player.update(keys, current_time)
307 self.collision_handler.update()
308 self.update_viewport()
309
310 self.draw_level(surface)
311
312
313 def draw_level(self, surface):
314 """Blits all images to screen"""
315 self.level_surface.blit(self.town_map['surface'], self.viewport, self.viewport)
316 self.level_surface.blit(self.player.image, self.player.rect)
317
318 surface.blit(self.level_surface, (0,0), self.viewport)
319
320
321 def update_viewport(self):
322 """Viewport stays centered on character, unless at edge of map"""
323 self.viewport.center = self.player.rect.center
324 self.viewport.clamp_ip(self.level_rect)
325
326
327
328
329
330
331
332
333
334