all repos — Legends-RPG @ f2dca0d393a15a440a0a97993509345ca515d575

A fantasy mini-RPG built with Python and Pygame.

data/tilemap.py (view raw)

  1__author__ = 'justinarmstrong'
  2
  3import os
  4import pygame as pg
  5from . import tools, setup
  6from . components import person, portal
  7from . import constants as c
  8
  9
 10def create_town_sprite_sheet_dict():
 11    """Create a dictionary of sprite sheet tiles"""
 12    tile_dict = {}
 13    tileset1 = setup.GFX['tileset1']
 14    tileset2 = setup.GFX['tileset2']
 15    tileset3 = setup.GFX['tileset3']
 16    shopsigns = setup.GFX['shopsigns']
 17    castle_door = setup.GFX['castledoor']
 18    medieval_signs = setup.GFX['medievalsigns']
 19    house = setup.GFX['house']
 20    houseoverworld = setup.GFX['houseoverworld']
 21    oldmanhouse = setup.GFX['house1']
 22    evilcastle = setup.GFX['evilcastle']
 23
 24    tile_dict['pavement'] = get_tile(32, 48, tileset2)
 25    tile_dict['house wall'] = get_tile(64, 48, tileset2)
 26    tile_dict['house roof'] = get_tile(0, 144, tileset2)
 27    tile_dict['house door'] = get_tile(48, 64, tileset2)
 28    tile_dict['tree'] = get_tile(80, 48, tileset1, 16, 32)
 29    tile_dict['well'] = get_tile(96, 50, tileset1, 16, 32)
 30    tile_dict['moat'] = get_tile(16, 16, tileset2)
 31    tile_dict['fence'] = get_tile(48, 64, tileset1)
 32    tile_dict['grass'] = get_tile(0, 16, tileset1)
 33    tile_dict['sword'] = get_tile(96, 0, shopsigns, 32, 32)
 34    tile_dict['shield'] = get_tile(64, 0, shopsigns, 32, 32)
 35    tile_dict['potion'] = get_tile(32, 0, shopsigns, 32, 32)
 36    tile_dict['gem'] = get_tile(0, 0, shopsigns, 32, 32)
 37    tile_dict['castle bridge'] = get_tile(48, 27, tileset1, 16, 32 )
 38    tile_dict['flower1'] = get_tile(64, 64, tileset2)
 39    tile_dict['flower2'] = get_tile(80, 64, tileset2)
 40    tile_dict['horiz castle wall'] = get_tile(32, 0, tileset3, 48, 32)
 41    tile_dict['left vert castle wall'] = get_tile(0, 16, tileset3)
 42    tile_dict['right vert castle wall'] = get_tile(162, 16, tileset3)
 43    tile_dict['castle tower'] = get_tile(116, 16, tileset1, 48, 64)
 44    tile_dict['main castle roof'] = get_tile(0, 0, tileset1, 160, 16)
 45    tile_dict['left castle roof piece'] = get_tile(0, 0, tileset1, 48, 16)
 46    tile_dict['right castle roof piece'] = get_tile(112, 0, tileset1, 48, 16)
 47    tile_dict['castle side'] = get_tile(0, 72, tileset3)
 48    tile_dict['castle door'] = get_tile(0, 0, castle_door, 64, 96)
 49    tile_dict['carpet topleft'] = get_tile(112, 112, tileset2)
 50    tile_dict['carpet topright'] = get_tile(144, 112, tileset2)
 51    tile_dict['carpet bottomleft'] = get_tile(112, 144, tileset2)
 52    tile_dict['carpet bottomright'] = get_tile(144, 144, tileset2)
 53    tile_dict['carpet bottom'] = get_tile(128, 144, tileset2)
 54    tile_dict['carpet top'] = get_tile(128, 112, tileset2)
 55    tile_dict['carpet left'] = get_tile(112, 128, tileset2)
 56    tile_dict['carpet right'] = get_tile(144, 128, tileset2)
 57    tile_dict['carpet center'] = get_tile(128, 128, tileset2)
 58    tile_dict['castle window'] = get_tile(128, 59, tileset1)
 59    tile_dict['marble floor'] = get_tile(80, 96, tileset3)
 60    tile_dict['inn sign'] = get_tile(0, 96, medieval_signs, 32, 32)
 61    tile_dict['banner1'] = get_tile(112, 38, tileset3, 16, 22)
 62    tile_dict['banner2'] = get_tile(128, 38, tileset3, 16, 22)
 63    tile_dict['banner3'] = get_tile(144, 38, tileset3, 16, 22)
 64    tile_dict['black tile'] = make_black_surface_tile()
 65    tile_dict['bed'] = get_tile(456, 206, house, 48, 82)
 66    tile_dict['shelves'] = get_tile(352, 116, house, 160, 70)
 67    tile_dict['chair'] = get_tile(323, 256, house, 32, 32)
 68    tile_dict['table'] = get_tile(82, 161, tileset3, 46, 32)
 69    tile_dict['fancy carpet'] = get_tile(112, 96, tileset3, 64, 64)
 70    tile_dict['column'] = get_tile(64, 96, tileset3, 16, 48)
 71    tile_dict['bottomwater1'] = get_tile(16, 32, tileset2)
 72    tile_dict['bottomwater2'] = get_tile(32, 32, tileset2)
 73    tile_dict['bottomwater3'] = get_tile(48, 32, tileset2)
 74    tile_dict['topwater1'] = get_tile(16, 0, tileset2)
 75    tile_dict['topwater2'] = get_tile(32, 0, tileset2)
 76    tile_dict['topwater3'] = get_tile(48, 0, tileset2)
 77    tile_dict['leftwater1'] = get_tile(80, 0, tileset2)
 78    tile_dict['leftwater2'] = get_tile(80, 16, tileset2)
 79    tile_dict['leftwater3'] = get_tile(0, 16, tileset2)
 80    tile_dict['rightwater1'] = get_tile(144, 0, tileset2)
 81    tile_dict['rightwater2'] = get_tile(144, 16, tileset2)
 82    tile_dict['rightwater3'] = get_tile(64, 16, tileset2)
 83    tile_dict['houseoverworld'] = get_tile(0, 0, houseoverworld, 128, 128)
 84    tile_dict['oldmanhouse'] = get_tile(0, 0, oldmanhouse, 32, 32)
 85    tile_dict['evilcastle'] = get_tile(0, 0, evilcastle, 128, 128)
 86
 87    return tile_dict
 88
 89def create_layer1_tile_code_dict():
 90    """Creates a dictionary of codes to tiles for layer 1"""
 91    tile_dict = {'1': 'pavement',
 92                 '2': 'house wall',
 93                 '3': 'house roof',
 94                 'T': 'tree',
 95                 'W': 'well',
 96                 'M': 'moat',
 97                 'G': 'grass',
 98                 'B': 'castle bridge',
 99                 'V': 'left vert castle wall',
100                 'C': 'horiz castle wall',
101                 'X': 'right vert castle wall',
102                 'S': 'castle side',
103                 'Q': 'carpet topleft',
104                 'E': 'carpet topright',
105                 'J': 'carpet top',
106                 'R': 'carpet bottomleft',
107                 'U': 'carpet bottomright',
108                 'D': 'carpet bottom',
109                 'P': 'carpet left',
110                 'A': 'carpet right',
111                 'F': 'carpet center',
112                 'H': 'marble floor',
113                 'K': 'black tile',
114                 'L': 'topwater1',
115                 'N': 'topwater2',
116                 'Y': 'topwater3',
117                 'Z': 'leftwater1',
118                 '4': 'leftwater2',
119                 '5': 'leftwater3',
120                 '6': 'rightwater1',
121                 '7': 'rightwater2',
122                 '8': 'rightwater3',
123                 '9': 'bottomwater1',
124                 'a': 'bottomwater2',
125                 'b': 'bottomwater3'
126                }
127
128    return tile_dict
129
130def create_layer2_tile_code_dict():
131    """Creates a dictionary of tile codes for layer 2"""
132    tile_dict = {'D': 'house door',
133                 'F': 'fence',
134                 '$': 'flower1',
135                 '*': 'flower2',
136                 'T': 'castle tower',
137                 'W': 'left vert castle wall',
138                 'M': 'main castle roof',
139                 'L': 'left castle roof piece',
140                 'R': 'right castle roof piece',
141                 '#': 'tree',
142                 'O': 'castle door',
143                 'Q': 'castle window',
144                 'A': 'banner1',
145                 'B': 'banner2',
146                 'C': 'banner3',
147                 'E': 'bed',
148                 'G': 'shelves',
149                 'H': 'chair',
150                 'I': 'table',
151                 'J': 'fancy carpet',
152                 'K': 'column',
153                 'N': 'black tile',
154                 'P': 'houseoverworld',
155                 '4': 'oldmanhouse',
156                 '5': 'evilcastle'
157    }
158
159    return tile_dict
160
161def create_layer3_tile_code_dict():
162    """Creates a dictionary of tile codes for layer 3"""
163    tile_dict = {'W': 'sword',
164                 'A': 'shield',
165                 'P': 'potion',
166                 'M': 'gem',
167                 'I': 'inn sign',
168                 'B': 'chair'}
169
170    return tile_dict
171
172def make_level_portals_code_dict():
173    """Make the dictionary for codes for level portals"""
174    portal_dict = {'A': c.CASTLE,
175                   'B': c.TOWN,
176                   'C': c.INN,
177                   'D': c.MAGIC_SHOP,
178                   'E': c.POTION_SHOP,
179                   'F': c.WEAPON_SHOP,
180                   'G': c.ARMOR_SHOP,
181                   'H': c.HOUSE,
182                   'J': c.OVERWORLD,
183                   'K': c.BROTHER_HOUSE
184    }
185
186    return portal_dict
187
188def get_tile(x, y, tileset, width=16, height=16, scale=1):
189    """Gets the surface and rect for a tile"""
190    surface = get_image(x, y, width, height, tileset)
191    surface = pg.transform.scale(surface, (int(width*scale), int(height*scale)))
192    rect = surface.get_rect()
193
194    tile_dict = {'surface': surface,
195                 'rect': rect}
196
197    return tile_dict
198
199
200def make_black_surface_tile():
201    """Make a black surface"""
202    surface = pg.Surface((32, 32))
203    surface.fill(c.NEAR_BLACK_BLUE)
204    rect = surface.get_rect()
205    new_dict = {'surface': surface,
206                'rect': rect}
207
208    return new_dict
209
210
211def make_background(state_name, width, height):
212    """Creates the background surface that the rest of
213    the town map will be blitted on"""
214    size = (width*16, height*16)
215    surface = pg.Surface(size)
216    if state_name == c.TOWN or state_name == c.OVERWORLD:
217        tile = get_image(0, 0, 16, 16, setup.GFX['tileset2'])
218    else:
219        tile = pg.Surface((16, 16))
220        tile.fill(c.BLACK_BLUE)
221
222    rect = tile.get_rect()
223
224    for row in range(height):
225        for column in range(width):
226            rect.y = row * 16
227            rect.x = column * 16
228            surface.blit(tile, rect)
229
230    return surface
231
232
233def create_map_layer1(state, width, height):
234    """Creates the town from a tile map and creates a
235    surface on top of the background"""
236    map = make_background(state, width, height)
237
238    tile_map = open(os.path.join('data', 'states', state, 'layer1.txt'), 'r')
239
240    for row, line in enumerate(tile_map):
241        for column, letter in enumerate(line):
242            if letter not in layer1_tile_code_dict:
243                pass
244            else:
245                tile = tile_dict[layer1_tile_code_dict[letter]]
246                blit_tile_to_map(tile, row, column, map)
247
248    tile_map.close()
249
250    layer1_extra = create_map_layer2(state, width, height, 'layer1extra.txt')
251    map.blit(layer1_extra, (0,0))
252
253    map = scale_map(map)
254
255    return map
256
257
258def create_map_layer2(state, width, height, file_name='layer2.txt'):
259    """Creates doors and other items on top of the rest of the map"""
260    map = make_background(None, width, height)
261    map.set_colorkey(c.BLACK_BLUE)
262    layer2_tile_dict = create_layer2_tile_code_dict()
263
264    tile_map = open(os.path.join('data', 'states', state, file_name), 'r')
265
266    for row, line in enumerate(tile_map):
267        for column, letter in enumerate(line):
268            if letter not in layer2_tile_dict:
269                pass
270            else:
271                tile = tile_dict[layer2_tile_dict[letter]]
272                blit_tile_to_map(tile, row, column, map)
273
274    tile_map.close()
275
276    if file_name == 'layer2.txt':
277        map = pg.transform.scale2x(map)
278        map = create_map_layer3(map, state)
279
280    return map
281
282
283def scale_map(map):
284    """Double resolution of map to 32x32"""
285    map = pg.transform.scale2x(map)
286
287    return map
288
289
290def create_map_layer3(map, state):
291    """Layers for images that are already 32x32"""
292    tile_map = open(os.path.join('data', 'states', state, 'layer3.txt'), 'r')
293    layer3_tile_dict = create_layer3_tile_code_dict()
294
295    for row, line in enumerate(tile_map):
296        for column, letter in enumerate(line):
297            if letter not in layer3_tile_dict:
298                pass
299            else:
300                tile = tile_dict[layer3_tile_dict[letter]]
301                blit_tile_to_map(tile, row, column, map, 32)
302
303    tile_map.close()
304
305    return map
306
307
308def blit_tile_to_map(tile, row, column, map, side_length=16):
309    """Places tile to map"""
310    tile['rect'].x = column * side_length
311    tile['rect'].y = row * side_length
312
313    map.blit(tile['surface'], tile['rect'])
314
315
316def create_blockers(state):
317    """Creates invisible rect objects that will prevent the player from
318    walking into trees, buildings and other solid objects"""
319    tile_map = open(os.path.join('data', 'states', state, 'blockers.txt'), 'r')
320    blockers = []
321
322    for row, line in enumerate(tile_map):
323        for column, letter in enumerate(line):
324            if letter == 'B':
325                blockers.append(pg.Rect(column*32, row*32, 32, 32))
326
327    tile_map.close()
328
329    return blockers
330
331
332def make_level_surface(map):
333    """Creates the surface all images are blitted to"""
334    map_rect = map.get_rect()
335    size = map_rect.size
336
337
338    return pg.Surface(size).convert()
339
340
341def create_viewport(map):
342    """Create the viewport to view the level through"""
343    map_rect = map.get_rect()
344    return setup.SCREEN.get_rect(bottom=map_rect.bottom)
345
346
347def set_sprite_positions(player, level_sprites, state, game_data):
348    """Set the start positions for all the sprites in the level"""
349    start_pos_key = state + ' start pos'
350    x =  game_data[start_pos_key][0]*32
351    y = game_data[start_pos_key][1]*32
352    player.rect = pg.Rect(x, y, 32, 32)
353
354    tile_map = open(os.path.join('data', 'states', state, 'sprite_start_pos.txt'), 'r')
355
356    for row, line in enumerate(tile_map):
357        for column, letter in enumerate(line):
358            if letter == 'F':
359                fem_villager = person.FemaleVillager(column*32, row*32)
360                level_sprites.add(fem_villager)
361            elif letter == 'S':
362                soldier = person.Soldier(column*32, row*32)
363                level_sprites.add(soldier)
364            elif letter == 'A':
365                soldier = person.Soldier(column*32, row*32, 'right', 'resting')
366                level_sprites.add(soldier)
367            elif letter == 'B':
368                soldier = person.Soldier(column*32, row*32, 'left', 'resting')
369                level_sprites.add(soldier)
370            elif letter == 'C':
371                king = person.King(column*32, row*32, 'down', 'resting')
372                level_sprites.add(king)
373            elif letter == 'D':
374                well = person.Well(column*32, row*32)
375                level_sprites.add(well)
376            elif letter == 'E':
377                fem_villager = person.FemaleVillager2(column*32, row*32)
378                level_sprites.add(fem_villager)
379            elif letter == 'G':
380                devil_villager = person.Devil(column*32, row*32)
381                level_sprites.add(devil_villager)
382            elif letter == 'H':
383                old_villager = person.OldMan(column*32, row*32)
384                level_sprites.add(old_villager)
385            elif letter == 'J':
386                old_brother = person.OldManBrother(column*32, row*32)
387                level_sprites.add(old_brother)
388
389    tile_map.close()
390
391
392def make_level_portals(state):
393    """Create portals to different levels on doors"""
394    tile_map = open(os.path.join('data', 'states', state, 'portals.txt'), 'r')
395    portal_code_dict = make_level_portals_code_dict()
396    portal_group = pg.sprite.Group()
397
398    for row, line in enumerate(tile_map):
399        for column, letter in enumerate(line):
400            if letter not in portal_code_dict:
401                pass
402            else:
403                portal_group.add(portal.Portal(
404                    column, row, portal_code_dict[letter]))
405
406    return portal_group
407
408
409get_image = tools.get_image
410tile_dict = create_town_sprite_sheet_dict()
411layer1_tile_code_dict = create_layer1_tile_code_dict()
412