comparison pyntnclick/gamescreen.py @ 692:d6ded808cc33 pyntnclick

Much scene management refactoring.
author Jeremy Thurgood <firxen@gmail.com>
date Tue, 14 Feb 2012 13:39:05 +0200
parents e6a32df9199e
children c8b683dd56d3
comparison
equal deleted inserted replaced
691:60bf20849231 692:d6ded808cc33
76 def __init__(self, rect, gd, screen): 76 def __init__(self, rect, gd, screen):
77 self.bsize = gd.constants.button_size 77 self.bsize = gd.constants.button_size
78 super(InventoryView, self).__init__(rect, gd) 78 super(InventoryView, self).__init__(rect, gd)
79 self.screen = screen 79 self.screen = screen
80 self.game = screen.game 80 self.game = screen.game
81 self.scene_widget = screen.scene_widget
82 81
83 slots = (self.rect.width - self.MIN_UPDOWN_WIDTH) / self.bsize 82 slots = (self.rect.width - self.MIN_UPDOWN_WIDTH) / self.bsize
84 self.slots = [self.add(self.make_slot(i)) for i in range(slots)] 83 self.slots = [self.add(self.make_slot(i)) for i in range(slots)]
85 self.inv_offset = 0 84 self.inv_offset = 0
86 85
146 DETAIL_BORDER = 4 145 DETAIL_BORDER = 4
147 DETAIL_BORDER_COLOR = Color("black") 146 DETAIL_BORDER_COLOR = Color("black")
148 147
149 def __init__(self, rect, gd, scene, screen, is_detail=False): 148 def __init__(self, rect, gd, scene, screen, is_detail=False):
150 super(SceneWidget, self).__init__(rect, gd) 149 super(SceneWidget, self).__init__(rect, gd)
150 self.name = scene.NAME
151 self.scene = scene 151 self.scene = scene
152 self.screen = screen 152 self.screen = screen
153 self.game = screen.game 153 self.game = screen.game
154 self.add_callback(MOUSEBUTTONDOWN, self.mouse_down) 154 self.add_callback(MOUSEBUTTONDOWN, self.mouse_down)
155 self.add_callback(MOUSEMOTION, self.mouse_move) 155 self.add_callback(MOUSEMOTION, self.mouse_move)
161 self.close_button.add_callback('clicked', self.close) 161 self.close_button.add_callback('clicked', self.close)
162 self.add(self.close_button) 162 self.add(self.close_button)
163 163
164 def draw(self, surface): 164 def draw(self, surface):
165 self.scene.draw(surface.subsurface(self.rect)) 165 self.scene.draw(surface.subsurface(self.rect))
166 self.scene.draw_description(surface) 166 if self.parent.is_top(self):
167 self.scene.draw_description(surface)
167 super(SceneWidget, self).draw(surface) 168 super(SceneWidget, self).draw(surface)
168 if self.is_detail: 169 if self.is_detail:
169 border = self.rect.inflate(self.DETAIL_BORDER, self.DETAIL_BORDER) 170 border = self.rect.inflate(self.DETAIL_BORDER, self.DETAIL_BORDER)
170 pygame.draw.rect( 171 pygame.draw.rect(
171 surface, self.DETAIL_BORDER_COLOR, border, self.DETAIL_BORDER) 172 surface, self.DETAIL_BORDER_COLOR, border, self.DETAIL_BORDER)
172 173
174 @property
175 def highlight_cursor(self):
176 return (self.scene.current_thing
177 and self.scene.current_thing.is_interactive())
178
173 def queue_widget(self, widget): 179 def queue_widget(self, widget):
174 self._message_queue.append(widget) 180 self._message_queue.append(widget)
175 181
176 def mouse_down(self, event, widget): 182 def mouse_down(self, event, widget):
177 self.mouse_move(event, widget) 183 self.mouse_move(event, widget)
178 if event.button != 1: # We have a right/middle click 184 if event.button != 1: # We have a right/middle click
179 self.game.cancel_doodah(self.screen) 185 self.game.cancel_doodah(self.screen)
180 else: 186 else:
181 pos = self.global_to_local(event.pos) 187 pos = self.global_to_local(event.pos)
182 result = self.game.interact(pos) 188 result = self.scene.interact(self.game.tool, pos)
183 handle_result(result, self) 189 handle_result(result, self)
184 190
185 def animate(self): 191 def animate(self):
186 # XXX: if self.game.animate(): 192 # XXX: if self.game.animate():
187 # queue a redraw 193 # queue a redraw
188 # self.invalidate() 194 # self.invalidate()
189 # We do this here so we can get enter and leave events regardless 195 # We do this here so we can get enter and leave events regardless
190 # of what happens 196 # of what happens
191 result = self.game.check_enter_leave(self.screen) 197 # result = self.game.check_enter_leave(self.screen)
192 handle_result(result, self) 198 # handle_result(result, self)
193 if self._message_queue: 199 if self._message_queue:
194 # Only add a message if we're at the top 200 # Only add a message if we're at the top
195 if self.screen.screen_modal.is_top(self.screen.inner_container): 201 if self.screen.screen_modal.is_top(self.screen.inner_container):
196 widget = self._message_queue.pop(0) 202 widget = self._message_queue.pop(0)
197 self.screen.screen_modal.add(widget) 203 self.screen.screen_modal.add(widget)
218 widget.rect.center = self.rect.center 224 widget.rect.center = self.rect.center
219 # We abuse animate so we can queue multiple results 225 # We abuse animate so we can queue multiple results
220 # according 226 # according
221 self.queue_widget(widget) 227 self.queue_widget(widget)
222 228
223 def show_detail(self, detail):
224 self.screen.show_detail(detail)
225
226 def close(self, event, widget): 229 def close(self, event, widget):
227 self.screen.close_detail(self) 230 self.screen.close_detail(self)
228
229 def end_game(self):
230 self.screen.change_screen('end')
231 231
232 232
233 class ToolBar(Container): 233 class ToolBar(Container):
234 def __init__(self, rect, gd, screen): 234 def __init__(self, rect, gd, screen):
235 self.screen = screen 235 self.screen = screen
282 def setup(self): 282 def setup(self):
283 super(GameScreen, self).setup() 283 super(GameScreen, self).setup()
284 self.gd.running = False 284 self.gd.running = False
285 self.create_initial_state = self.gd.initial_state 285 self.create_initial_state = self.gd.initial_state
286 self.container.add_callback(KEYDOWN, self.key_pressed) 286 self.container.add_callback(KEYDOWN, self.key_pressed)
287 self.scene_widget = None
288 287
289 def _clear_all(self): 288 def _clear_all(self):
290 for widget in self.container.children[:]: 289 for widget in self.container.children[:]:
291 self.container.remove(widget) 290 self.container.remove(widget)
292 291
293 def process_event(self, event_name, data): 292 def process_event(self, event_name, data):
294 if event_name == 'restart': 293 getattr(self, 'game_event_%s' % event_name, lambda d: None)(data)
295 self.start_game() 294
296 elif event_name == 'inventory': 295 def game_event_restart(self, data):
297 self.inventory.update_slots()
298 elif event_name == 'change_scene':
299 self.change_scene(data)
300
301 def start_game(self):
302 self._clear_all() 296 self._clear_all()
303 self.game = self.create_initial_state() 297 self.game = self.create_initial_state()
304 298
305 self.screen_modal = self.container.add( 299 self.screen_modal = self.container.add(
306 ModalStackContainer(self.container.rect.copy(), self.gd)) 300 ModalStackContainer(self.container.rect.copy(), self.gd))
311 rect = Rect(0, 0, self.surface_size[0], 305 rect = Rect(0, 0, self.surface_size[0],
312 self.surface_size[1] - toolbar_height) 306 self.surface_size[1] - toolbar_height)
313 307
314 self.scene_modal = self.inner_container.add( 308 self.scene_modal = self.inner_container.add(
315 ModalStackContainer(rect, self.gd)) 309 ModalStackContainer(rect, self.gd))
316 self.change_scene(None)
317
318 self.toolbar = self.inner_container.add( 310 self.toolbar = self.inner_container.add(
319 ToolBar((0, rect.height), self.gd, self)) 311 ToolBar((0, rect.height), self.gd, self))
320 self.inventory = self.toolbar.inventory 312 self.inventory = self.toolbar.inventory
321 313
314 self.game.change_scene
322 self.gd.running = True 315 self.gd.running = True
323 316
317 def game_event_inventory(self, data):
318 self.inventory.update_slots()
319
320 def game_event_change_scene(self, data):
321 scene_name = data['name']
322 if data['detail']:
323 self.show_detail(scene_name)
324 else:
325 self.change_scene(scene_name)
326
324 def change_scene(self, scene_name): 327 def change_scene(self, scene_name):
325 self.scene_modal.remove_all() 328 for scene_widget in reversed(self.scene_modal.children[:]):
326 self.scene_widget = self.scene_modal.add( 329 self.scene_modal.remove(scene_widget)
327 SceneWidget(self.scene_modal.rect.copy(), self.gd, 330 scene_widget.scene.leave()
328 self.game.current_scene, self)) 331 scene = self.game.scenes[scene_name]
332 self.game.current_scene = scene
333 self._add_scene(scene)
329 334
330 def show_detail(self, detail_name): 335 def show_detail(self, detail_name):
331 detail = self.game.set_current_detail(detail_name) 336 self._add_scene(self.game.detail_views[detail_name], True)
332 detail_rect = Rect((0, 0), detail.get_detail_size()) 337
333 detail_rect.center = self.scene_modal.rect.center 338 def _add_scene(self, scene, detail=False):
334 self.scene_modal.add( 339 rect = self.scene_modal.rect.copy()
335 SceneWidget(detail_rect, self.gd, detail, self, is_detail=True)) 340 if detail:
341 rect = Rect((0, 0), scene.get_detail_size())
342 rect.center = self.scene_modal.rect.center
343
344 scene_widget = self.scene_modal.add(
345 SceneWidget(rect, self.gd, scene, self, detail))
346
347 handle_result(scene.enter(), scene_widget)
336 348
337 def close_detail(self, detail): 349 def close_detail(self, detail):
338 self.scene_modal.remove(detail) 350 self.scene_modal.remove(detail)
351 detail.scene.leave()
339 352
340 def animate(self): 353 def animate(self):
341 """Animate the scene widgets""" 354 """Animate the scene widgets"""
342 for scene_widget in self.scene_modal.children: 355 for scene_widget in self.scene_modal.children:
343 scene_widget.animate() 356 scene_widget.animate()