all repos — Legends-RPG @ bca46b8c54d44e37d0ae536923d18721651ea045

A fantasy mini-RPG built with Python and Pygame.

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