all repos — Legends-RPG @ 88d77458a8099a4f68eaee9b37e58a836efe89bc

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