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 .. components import person, textbox, portal
13from . import player_menu
14from .. import tilerender
15from .. import setup
16
17
18class LevelState(tools._State):
19 def __init__(self):
20 super(LevelState, self).__init__()
21 self.name = None
22 self.tmx_map = None
23 self.map_width = None
24 self.map_height = None
25
26 def startup(self, current_time, game_data):
27 """Called when the State object is created"""
28 self.game_data = game_data
29 self.current_time = current_time
30 self.state = 'normal'
31 self.allow_input = False
32 self.renderer = tilerender.Renderer(self.tmx_map)
33 self.map_image = self.renderer.make_2x_map()
34
35 self.viewport = self.make_viewport(self.map_image)
36 self.level_surface = self.make_level_surface(self.map_image)
37 self.level_rect = self.level_surface.get_rect()
38 self.player = None
39 self.portals = None
40 self.player = person.Player(game_data['last direction'])
41 self.player = self.make_player()
42 self.blockers = self.make_blockers()
43 self.sprites = pg.sprite.Group()
44 #self.start_positions = tm.set_sprite_positions(self.player,
45 # self.sprites,
46 # self.name,
47 # self.game_data)
48 #self.set_sprite_dialogue()
49 self.collision_handler = collision.CollisionHandler(self.player,
50 self.blockers,
51 self.sprites)
52
53 self.dialogue_handler = textbox.TextHandler(self)
54 self.state_dict = self.make_state_dict()
55 self.portals = self.make_level_portals()
56 self.menu_screen = player_menu.Player_Menu(game_data, self)
57
58 def make_viewport(self, map_image):
59 """Create the viewport to view the level through"""
60 map_rect = map_image.get_rect()
61 return setup.SCREEN.get_rect(bottom=map_rect.bottom)
62
63 def make_level_surface(self, map_image):
64 """Creates the surface all images are blitted to"""
65 map_rect = map_image.get_rect()
66 map_width = map_rect.width
67 if self.name == 'town':
68 map_height = map_rect.height - 32
69 else:
70 map_height = map_rect.height
71 size = map_width, map_height
72 return pg.Surface(size).convert()
73
74 def make_player(self):
75 """Makes the player and sets location"""
76 player = person.Player(self.game_data['last direction'])
77
78 for object in self.renderer.tmx_data.getObjects():
79 properties = object.__dict__
80 if properties['name'] == 'player start':
81 posx = properties['x'] * 2
82 posy = (properties['y'] * 2) - 32
83 player.rect.x = posx
84 player.rect.y = posy
85
86 return player
87
88 def make_blockers(self):
89 """Make the blockers for the level"""
90 blockers = []
91
92 for object in self.renderer.tmx_data.getObjects():
93 properties = object.__dict__
94 if properties['name'] == 'blocker':
95 left = properties['x'] * 2
96 top = ((properties['y']) * 2) - 32
97 blocker = pg.Rect(left, top, 32, 32)
98 blockers.append(blocker)
99
100 return blockers
101
102
103 def set_sprite_dialogue(self):
104 """Sets unique dialogue for each sprite"""
105 pass
106
107
108 def make_state_dict(self):
109 """Make a dictionary of states the level can be in"""
110 state_dict = {'normal': self.running_normally,
111 'dialogue': self.handling_dialogue,
112 'menu': self.goto_menu}
113
114 return state_dict
115
116 def make_level_portals(self):
117 """Make the portals to switch state"""
118 portal_group = pg.sprite.Group()
119
120 for object in self.renderer.tmx_data.getObjects():
121 properties = object.__dict__
122 if properties['name'] == 'portal':
123 posx = properties['x'] * 2
124 posy = (properties['y'] * 2) - 32
125 new_state = properties['new state']
126 portal_group.add(portal.Portal(posx, posy, new_state))
127
128
129 return portal_group
130
131
132 def running_normally(self, surface, keys, current_time):
133 """Update level normally"""
134 self.check_for_dialogue()
135 self.check_for_portals()
136 self.player.update(keys, current_time)
137 #self.sprites.update(current_time)
138 self.collision_handler.update(keys, current_time)
139 #self.dialogue_handler.update(keys, current_time)
140 self.check_for_menu(keys)
141 self.viewport_update()
142
143 self.draw_level(surface)
144
145
146 def check_for_portals(self):
147 """Check if the player walks into a door, requiring a level change"""
148 portal = pg.sprite.spritecollideany(self.player, self.portals)
149
150 if portal and self.player.state == 'resting':
151 self.player.location = self.player.get_tile_location()
152 self.next = portal.name
153 print self.next
154 self.update_game_data()
155 self.done = True
156
157
158 def check_for_menu(self, keys):
159 """Check if player hits enter to go to menu"""
160 if keys[pg.K_RETURN] and self.allow_input:
161 if self.player.state == 'resting':
162 self.state = 'menu'
163 self.allow_input = False
164
165 if not keys[pg.K_RETURN]:
166 self.allow_input = True
167
168
169 def update_game_data(self):
170 """Update the persistant game data dictionary"""
171 self.game_data['last location'] = self.player.location
172 self.game_data['last direction'] = self.player.direction
173 self.game_data['last state'] = self.name
174
175 self.set_new_start_pos()
176
177
178 def set_new_start_pos(self):
179 """Set new start position based on previous state"""
180 location = copy.deepcopy(self.game_data['last location'])
181 direction = self.game_data['last direction']
182 state = self.game_data['last state']
183
184 if self.next == 'player menu':
185 pass
186 elif direction == 'up':
187 location[1] += 1
188 elif direction == 'down':
189 location[1] -= 1
190 elif direction == 'left':
191 location[0] += 1
192 elif direction == 'right':
193 location[0] -= 1
194
195 self.game_data[state + ' start pos'] = location
196
197
198 def handling_dialogue(self, surface, keys, current_time):
199 """Update only dialogue boxes"""
200 #self.dialogue_handler.update(keys, current_time)
201 self.draw_level(surface)
202
203
204 def goto_menu(self, surface, keys, *args):
205 """Go to menu screen"""
206 self.menu_screen.update(surface, keys)
207 self.menu_screen.draw(surface)
208
209
210 def check_for_dialogue(self):
211 """Check if the level needs to freeze"""
212 #if self.dialogue_handler.textbox:
213 # self.state = 'dialogue'
214 pass
215
216 def update(self, surface, keys, current_time):
217 """Updates state"""
218 state_function = self.state_dict[self.state]
219 state_function(surface, keys, current_time)
220
221 def viewport_update(self):
222 """Viewport stays centered on character, unless at edge of map"""
223 self.viewport.center = self.player.rect.center
224 self.viewport.clamp_ip(self.level_rect)
225
226 def draw_level(self, surface):
227 """Blits all images to screen"""
228 self.level_surface.blit(self.map_image, self.viewport, self.viewport)
229 self.level_surface.blit(self.player.image, self.player.rect)
230 self.sprites.draw(self.level_surface)
231
232 surface.blit(self.level_surface, (0, 0), self.viewport)
233 self.dialogue_handler.draw(surface)
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249