all repos — Legends-RPG @ f2dca0d393a15a440a0a97993509345ca515d575

A fantasy mini-RPG built with Python and Pygame.

data/states/level_state.py (view raw)

  1__author__ = 'justinarmstrong'
  2"""
  3This is the base class all level states (i.e. states
  4where the player can move around the screen) inherit
  5from.  This class inherits from the generic state class
  6found in the tools.py module.
  7"""
  8
  9import copy
 10import pygame as pg
 11from .. import tools, collision
 12from .. import tilemap as tm
 13from .. components import person, textbox
 14from . import player_menu
 15from .. import tilerender
 16from .. import setup
 17
 18
 19class LevelState(tools._State):
 20    def __init__(self):
 21        super(LevelState, self).__init__()
 22        self.name = None
 23        self.tmx_map = None
 24        self.map_width = None
 25        self.map_height = None
 26
 27    def startup(self, current_time, game_data):
 28        """Called when the State object is created"""
 29        self.game_data = game_data
 30        self.current_time = current_time
 31        self.state = 'normal'
 32        self.allow_input = False
 33        self.renderer = tilerender.Renderer(self.tmx_map)
 34        self.map_image = self.renderer.make_2x_map()
 35
 36        self.viewport = self.make_viewport(self.map_image)
 37        self.level_surface = self.make_level_surface(self.map_image)
 38        self.level_rect = self.level_surface.get_rect()
 39        self.player = None
 40        self.portals = None
 41        self.player = person.Player(game_data['last direction'])
 42        self.player = self.make_player()
 43        self.blockers = self.make_blockers()
 44        self.sprites = pg.sprite.Group()
 45        #self.start_positions = tm.set_sprite_positions(self.player,
 46        #                                               self.sprites,
 47        #                                               self.name,
 48        #                                               self.game_data)
 49        #self.set_sprite_dialogue()
 50        self.collision_handler = collision.CollisionHandler(self.player,
 51                                                            self.blockers,
 52                                                            self.sprites)
 53
 54        self.dialogue_handler = textbox.TextHandler(self)
 55        self.state_dict = self.make_state_dict()
 56        #self.portals = tm.make_level_portals(self.name)
 57        self.menu_screen = player_menu.Player_Menu(game_data, self)
 58
 59    def make_viewport(self, map_image):
 60        """Create the viewport to view the level through"""
 61        map_rect = map_image.get_rect()
 62        return setup.SCREEN.get_rect(bottom=map_rect.bottom)
 63
 64    def make_level_surface(self, map_image):
 65        """Creates the surface all images are blitted to"""
 66        map_rect = map_image.get_rect()
 67        size = map_rect.size
 68        return pg.Surface(size).convert()
 69
 70    def make_player(self):
 71        """Makes the player and sets location"""
 72        player = person.Player(self.game_data['last direction'])
 73
 74        for object in self.renderer.tmx_data.getObjects():
 75            property_dict = object.__dict__
 76            if property_dict['name'] == 'Player start':
 77                player.rect.x = int(property_dict['posx']) * 32
 78                player.rect.y = int(property_dict['posy']) * 32
 79
 80        return player
 81
 82    def make_blockers(self):
 83        """Make the blockers for the level"""
 84        blockers = []
 85
 86        for object in self.renderer.tmx_data.getObjects():
 87            properties = object.__dict__
 88            if properties['name'] == 'blocker':
 89                left = properties['x'] * 2
 90                top = ((properties['y']) * 2) - 32
 91                blocker = pg.Rect(left, top, 32, 32)
 92                blockers.append(blocker)
 93
 94        return blockers
 95
 96
 97    def set_sprite_dialogue(self):
 98        """Sets unique dialogue for each sprite"""
 99        pass
100
101
102    def make_state_dict(self):
103        """Make a dictionary of states the level can be in"""
104        state_dict = {'normal': self.running_normally,
105                      'dialogue': self.handling_dialogue,
106                      'menu': self.goto_menu}
107
108        return state_dict
109
110
111    def running_normally(self, surface, keys, current_time):
112        """Update level normally"""
113        self.check_for_dialogue()
114        self.check_for_portals()
115        self.player.update(keys, current_time)
116        #self.sprites.update(current_time)
117        self.collision_handler.update(keys, current_time)
118        #self.dialogue_handler.update(keys, current_time)
119        self.check_for_menu(keys)
120        self.viewport_update()
121
122        self.draw_level(surface)
123
124
125    def check_for_portals(self):
126        """Check if the player walks into a door, requiring a level change"""
127        """
128        portal = pg.sprite.spritecollideany(self.player, self.portals)
129
130        if portal and self.player.state == 'resting':
131            self.player.location = self.player.get_tile_location()
132            self.next = portal.name
133            self.update_game_data()
134            self.done = True
135        """
136        pass
137
138
139    def check_for_menu(self, keys):
140        """Check if player hits enter to go to menu"""
141        if keys[pg.K_RETURN] and self.allow_input:
142            if self.player.state == 'resting':
143                self.state = 'menu'
144                self.allow_input = False
145
146        if not keys[pg.K_RETURN]:
147            self.allow_input = True
148
149
150    def update_game_data(self):
151        """Update the persistant game data dictionary"""
152        self.game_data['last location'] = self.player.location
153        self.game_data['last direction'] = self.player.direction
154        self.game_data['last state'] = self.name
155
156        self.set_new_start_pos()
157
158
159    def set_new_start_pos(self):
160        """Set new start position based on previous state"""
161        location = copy.deepcopy(self.game_data['last location'])
162        direction = self.game_data['last direction']
163        state = self.game_data['last state']
164
165        if self.next == 'player menu':
166            pass
167        elif direction == 'up':
168            location[1] += 1
169        elif direction == 'down':
170            location[1] -= 1
171        elif direction == 'left':
172            location[0] += 1
173        elif direction == 'right':
174            location[0] -= 1
175
176        self.game_data[state + ' start pos'] = location
177
178
179    def handling_dialogue(self, surface, keys, current_time):
180        """Update only dialogue boxes"""
181        #self.dialogue_handler.update(keys, current_time)
182        self.draw_level(surface)
183
184
185    def goto_menu(self, surface, keys, *args):
186        """Go to menu screen"""
187        self.menu_screen.update(surface, keys)
188        self.menu_screen.draw(surface)
189
190
191    def check_for_dialogue(self):
192        """Check if the level needs to freeze"""
193        #if self.dialogue_handler.textbox:
194        #    self.state = 'dialogue'
195        pass
196
197    def update(self, surface, keys, current_time):
198        """Updates state"""
199        state_function = self.state_dict[self.state]
200        state_function(surface, keys, current_time)
201
202    def viewport_update(self):
203        """Viewport stays centered on character, unless at edge of map"""
204        self.viewport.center = self.player.rect.center
205        self.viewport.clamp_ip(self.level_rect)
206
207    def draw_level(self, surface):
208        """Blits all images to screen"""
209        self.level_surface.blit(self.map_image, self.viewport, self.viewport)
210        self.level_surface.blit(self.player.image, self.player.rect)
211        self.sprites.draw(self.level_surface)
212
213
214
215        surface.blit(self.level_surface, (0, 0), self.viewport)
216        self.dialogue_handler.draw(surface)
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232