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