all repos — Legends-RPG @ d8373003d109394bfb66273042e2a2fb96a2b738

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