all repos — Legends-RPG @ cfe27f199eb035566a7a0cb057b3d0c482ee51c8

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