all repos — Legends-RPG @ d9c581e5d018bd9cee12f2fb8723f65375a79347

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
 15
 16
 17class LevelState(tools._State):
 18    def __init__(self):
 19        super(LevelState, self).__init__()
 20        self.name = None
 21        self.map_width = None
 22        self.map_height = None
 23
 24    def startup(self, current_time, game_data):
 25        """Called when the State object is created"""
 26        self.game_data = game_data
 27        self.current_time = current_time
 28        self.state = 'normal'
 29        self.allow_input = False
 30        self.background = tm.create_map_layer1(self.name,
 31                                               self.map_width,
 32                                               self.map_height)
 33        self.foreground = tm.create_map_layer2(self.name,
 34                                               self.map_width,
 35                                               self.map_height)
 36        self.viewport = tm.create_viewport(self.background)
 37        self.blockers = tm.create_blockers(self.name)
 38        self.level_surface = tm.make_level_surface(self.background)
 39        self.level_rect = self.level_surface.get_rect()
 40        self.player = person.Player(game_data['last direction'])
 41        self.sprites = pg.sprite.Group()
 42        self.start_positions = tm.set_sprite_positions(self.player,
 43                                                       self.sprites,
 44                                                       self.name,
 45                                                       self.game_data)
 46        self.set_sprite_dialogue()
 47        self.collision_handler = collision.CollisionHandler(self.player,
 48                                                            self.blockers,
 49                                                            self.sprites)
 50        self.dialogue_handler = textbox.TextHandler(self)
 51        self.state_dict = self.make_state_dict()
 52        self.portals = tm.make_level_portals(self.name)
 53        self.menu_screen = player_menu.Player_Menu(game_data, self)
 54
 55
 56    def set_sprite_dialogue(self):
 57        """Sets unique dialogue for each sprite"""
 58        pass
 59
 60
 61    def make_state_dict(self):
 62        """Make a dictionary of states the level can be in"""
 63        state_dict = {'normal': self.running_normally,
 64                      'dialogue': self.handling_dialogue,
 65                      'menu': self.goto_menu}
 66
 67        return state_dict
 68
 69
 70    def running_normally(self, surface, keys, current_time):
 71        """Update level normally"""
 72        self.check_for_dialogue()
 73        self.check_for_portals()
 74        self.player.update(keys, current_time)
 75        self.sprites.update(current_time)
 76        self.collision_handler.update(keys, current_time)
 77        self.dialogue_handler.update(keys, current_time)
 78        self.check_for_menu(keys)
 79        self.viewport_update()
 80
 81        self.draw_level(surface)
 82
 83
 84    def check_for_portals(self):
 85        """Check if the player walks into a door, requiring a level change"""
 86        portal = pg.sprite.spritecollideany(self.player, self.portals)
 87
 88        if portal and self.player.state == 'resting':
 89            self.player.location = self.player.get_tile_location()
 90            self.next = portal.name
 91            self.update_game_data()
 92            self.done = True
 93
 94
 95    def check_for_menu(self, keys):
 96        """Check if player hits enter to go to menu"""
 97        if keys[pg.K_RETURN] and self.allow_input:
 98            if self.player.state == 'resting':
 99                self.state = 'menu'
100                self.allow_input = False
101
102
103        if not keys[pg.K_RETURN]:
104            self.allow_input = True
105
106
107    def update_game_data(self):
108        """Update the persistant game data dictionary"""
109        self.game_data['last location'] = self.player.location
110        self.game_data['last direction'] = self.player.direction
111        self.game_data['last state'] = self.name
112
113        self.set_new_start_pos()
114
115
116    def set_new_start_pos(self):
117        """Set new start position based on previous state"""
118        location = copy.deepcopy(self.game_data['last location'])
119        direction = self.game_data['last direction']
120        state = self.game_data['last state']
121
122        if self.next == 'player menu':
123            pass
124        elif direction == 'up':
125            location[1] += 1
126        elif direction == 'down':
127            location[1] -= 1
128        elif direction == 'left':
129            location[0] += 1
130        elif direction == 'right':
131            location[0] -= 1
132
133        self.game_data[state + ' start pos'] = location
134
135
136    def handling_dialogue(self, surface, keys, current_time):
137        """Update only dialogue boxes"""
138        self.dialogue_handler.update(keys, current_time)
139        self.draw_level(surface)
140
141
142    def goto_menu(self, surface, keys, *args):
143        """Go to menu screen"""
144        self.menu_screen.update(surface, keys)
145        self.menu_screen.draw(surface)
146
147
148    def check_for_dialogue(self):
149        """Check if the level needs to freeze"""
150        if self.dialogue_handler.textbox:
151            self.state = 'dialogue'
152
153    def update(self, surface, keys, current_time):
154        """Updates state"""
155        state_function = self.state_dict[self.state]
156        state_function(surface, keys, current_time)
157
158    def viewport_update(self):
159        """Viewport stays centered on character, unless at edge of map"""
160        self.viewport.center = self.player.rect.center
161        self.viewport.clamp_ip(self.level_rect)
162
163    def draw_level(self, surface):
164        """Blits all images to screen"""
165        self.level_surface.blit(self.background, self.viewport, self.viewport)
166        self.level_surface.blit(self.player.image, self.player.rect)
167        self.sprites.draw(self.level_surface)
168        self.level_surface.blit(self.foreground, self.viewport, self.viewport)
169
170
171        surface.blit(self.level_surface, (0, 0), self.viewport)
172        self.dialogue_handler.draw(surface)
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187