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