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