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):
18 super(LevelState, self).__init__(name)
19
20
21 def startup(self, current_time, persist):
22 """Called when the State object is created"""
23 self.persist = persist
24 self.current_time = current_time
25 self.state = 'normal'
26 self.town_map = tm.create_town_map(self.name)
27 self.viewport = tm.create_viewport(self.town_map)
28 self.blockers = tm.create_blockers(self.name)
29 self.level_surface = tm.create_level_surface(self.town_map)
30 self.level_rect = self.level_surface.get_rect()
31 self.player = person.Player(persist['last direction'])
32 self.level_sprites = pg.sprite.Group()
33 self.start_positions = tm.set_sprite_positions(self.player,
34 self.level_sprites,
35 self.name,
36 self.persist)
37 self.set_sprite_dialogue()
38 self.collision_handler = collision.CollisionHandler(self.player,
39 self.blockers,
40 self.level_sprites)
41 self.dialogue_handler = textbox.DialogueHandler(self.player,
42 self.level_sprites,
43 self)
44 self.state_dict = self.make_state_dict()
45 self.portals = tm.make_level_portals(self.name)
46 self.parent_level = None
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.level_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.persist['last location'] = self.player.location
89 self.persist['last direction'] = self.player.direction
90 self.persist['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.persist['last location'])
98 direction = self.persist['last direction']
99 state = self.persist['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.persist[state + ' start pos'] = location
111
112
113
114
115
116
117 def handling_dialogue(self, surface, keys, current_time):
118 """Update only dialogue boxes"""
119 self.dialogue_handler.update(keys, current_time)
120 self.draw_level(surface)
121
122
123 def check_for_dialogue(self):
124 """Check if the level needs to freeze"""
125 if self.dialogue_handler.textbox:
126 self.state = 'dialogue'
127
128
129 def update(self, surface, keys, current_time):
130 """Updates state"""
131 state_function = self.state_dict[self.state]
132 state_function(surface, keys, current_time)
133
134
135 def viewport_update(self):
136 """Viewport stays centered on character, unless at edge of map"""
137 self.viewport.center = self.player.rect.center
138 self.viewport.clamp_ip(self.level_rect)
139
140
141 def draw_level(self, surface):
142 """Blits all images to screen"""
143 self.level_surface.blit(self.town_map['surface'], self.viewport, self.viewport)
144 self.level_surface.blit(self.player.image, self.player.rect)
145 self.level_sprites.draw(self.level_surface)
146
147 surface.blit(self.level_surface, (0, 0), self.viewport)
148 self.dialogue_handler.draw(surface)
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163