all repos — Legends-RPG @ 1207a1902825c44d03a01ec673bd3ab3c0156fc6

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        dict = {}
 31        tileset1 = setup.GFX['tileset1']
 32        tileset2 = setup.GFX['tileset2']
 33
 34
 35        dict['pavement'] = self.get_tile(32, 48, tileset2)
 36        dict['house wall'] = self.get_tile(64, 48, tileset2)
 37        dict['house roof'] = self.get_tile(0, 144, tileset2)
 38        dict['house door'] = self.get_tile(48, 64, tileset2)
 39        dict['tree'] = self.get_tile(80, 48, tileset1, 16, 32)
 40        dict['well'] = self.get_tile(96, 50, tileset1, 16, 32)
 41
 42        return dict
 43
 44
 45    def get_tile(self, x, y, tileset, width=16, height=16):
 46        """Gets the surface and rect for a tile"""
 47        surface = self.get_image(self, x, y, width, height, tileset)
 48        rect = surface.get_rect()
 49
 50        dict = {'surface': surface,
 51                'rect': rect}
 52
 53        return dict
 54
 55
 56    def create_town_map(self):
 57        """Blits the different layers of the map onto one surface"""
 58        map = self.create_background()
 59        map = self.create_map_layer1(map)
 60        map = self.create_map_layer2(map)
 61        map = self.scale_map(map)
 62
 63        return map
 64
 65
 66    def create_background(self):
 67        """Creates the background surface that the rest of
 68        the town map will be blitted on"""
 69        size = (25*16, 50*16)
 70        surface = pg.Surface(size)
 71        grass_tile = self.get_image(self, 0, 0, 16, 16, setup.GFX['tileset2'])
 72        grass_rect = grass_tile.get_rect()
 73
 74        for row in range(50):
 75            for column in range(25):
 76                grass_rect.y = row * 16
 77                grass_rect.x = column * 16
 78                surface.blit(grass_tile, grass_rect)
 79
 80        surface_rect = surface.get_rect()
 81
 82        background_dict = {'surface': surface,
 83                           'rect': surface_rect}
 84
 85        return background_dict
 86
 87
 88    def create_map_layer1(self, map):
 89        """Creates the town from a tile map and creates a
 90        surface on top of the background"""
 91        tile_map = open(os.path.join('data', 'states', 'town_map.txt'), 'r')
 92
 93        for row, line in enumerate(tile_map):
 94            for column, letter in enumerate(line):
 95                if letter == '1':
 96                    tile = self.town_map_dict['pavement']
 97                    self.blit_tile_to_map(tile, row, column, map)
 98
 99                elif letter == '2':
100                    tile = self.town_map_dict['house wall']
101                    self.blit_tile_to_map(tile, row, column, map)
102
103                elif letter == '3':
104                    tile = self.town_map_dict['house roof']
105                    self.blit_tile_to_map(tile, row, column, map)
106
107                elif letter == 'T':
108                    tile = self.town_map_dict['tree']
109                    self.blit_tile_to_map(tile, row, column, map)
110
111                elif letter == 'W':
112                    tile = self.town_map_dict['well']
113                    self.blit_tile_to_map(tile, row, column, map)
114
115        tile_map.close()
116
117        return map
118
119
120    def create_map_layer2(self, map):
121        """Creates doors and other items on top of the rest of the map"""
122        tile_map = open(os.path.join('data', 'states', 'town_layer2.txt'), 'r')
123
124        for row, line in enumerate(tile_map):
125            for column, letter in enumerate(line):
126                if letter == 'D':
127                    tile = self.town_map_dict['house door']
128                    self.blit_tile_to_map(tile, row, column, map)
129
130        tile_map.close()
131
132        return map
133
134
135    def scale_map(self, map):
136        """Double resolution of map to 32x32"""
137        map['surface'] = pg.transform.scale2x(map['surface'])
138        map['rect'] = map['surface'].get_rect()
139
140        return map
141
142
143    def blit_tile_to_map(self, tile, row, column, map):
144        """Places tile to map"""
145        tile['rect'].x = column * 16
146        tile['rect'].y = row * 16
147
148        map['surface'].blit(tile['surface'], tile['rect'])
149
150
151    def create_viewport(self):
152        """Create the viewport to view the level through"""
153        return setup.SCREEN.get_rect(bottom=self.town_map['rect'].bottom)
154
155
156    def create_level_surface(self):
157        """Creates the surface all images are blitted to"""
158        width = self.town_map['rect'].width
159        height = self.town_map['rect'].height
160
161        return pg.Surface((width, height)).convert()
162
163
164    def set_sprite_positions(self):
165        """Set the start positions for all the sprites in the level"""
166        tile_map = open(os.path.join('data', 'states', 'sprite_start_pos.txt'), 'r')
167        dict = {}
168
169        for row, line in enumerate(tile_map):
170            for column, letter in enumerate(line):
171                if letter == 'P':
172                    dict['player'] = pg.Rect(column*32, row*32, 32, 32)
173
174        self.player.rect = dict['player']
175
176        return dict
177
178
179    def update(self, surface, keys, current_time):
180        """Updates state"""
181        self.keys = keys
182        self.current_time = current_time
183        self.player.update(keys, current_time)
184        self.update_viewport()
185
186        self.draw_level(surface)
187
188
189    def draw_level(self, surface):
190        """Blits all images to screen"""
191        self.level_surface.blit(self.town_map['surface'], self.viewport, self.viewport)
192        self.level_surface.blit(self.player.image, self.player.rect)
193
194        surface.blit(self.level_surface, (0,0), self.viewport)
195
196
197    def update_viewport(self):
198        """Viewport stays centered on character, unless at edge of map"""
199        self.viewport.center = self.player.rect.center
200        self.viewport.clamp_ip(self.level_rect)
201
202
203
204
205
206
207
208
209
210