all repos — Legends-RPG @ ce2b2c848151d5a9365aee0fc44c1037638725ed

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