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