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