comparison pyntnclick/state.py @ 603:3ce19d33b51f pyntnclick

Rename state to game to not cause confusion with the other state
author Neil Muller <neil@dip.sun.ac.za>
date Sat, 11 Feb 2012 20:09:47 +0200
parents 59f1ee3f5632
children a25cd1c6335a
comparison
equal deleted inserted replaced
602:1aac5a3b17e1 603:3ce19d33b51f
20 self.close_detail = close_detail 20 self.close_detail = close_detail
21 self.end_game = end_game 21 self.end_game = end_game
22 22
23 def play_sound(self, scene_widget): 23 def play_sound(self, scene_widget):
24 if self.soundfile: 24 if self.soundfile:
25 sound = scene_widget.state.gd.sound.get_sound(self.soundfile) 25 sound = scene_widget.game.gd.sound.get_sound(self.soundfile)
26 sound.play() 26 sound.play()
27 27
28 def process(self, scene_widget): 28 def process(self, scene_widget):
29 """Helper function to do the right thing with a result object""" 29 """Helper function to do the right thing with a result object"""
30 self.play_sound(scene_widget) 30 self.play_sound(scene_widget)
50 if res: 50 if res:
51 # List may contain None's 51 # List may contain None's
52 res.process(scene_widget) 52 res.process(scene_widget)
53 53
54 54
55 class GameState(object): 55 class Game(object):
56 """Complete game state. 56 """Complete game state.
57 57
58 Game state consists of: 58 Game state consists of:
59 59
60 * items 60 * items
71 self.items = {} 71 self.items = {}
72 # list of item objects in inventory 72 # list of item objects in inventory
73 self.inventory = [] 73 self.inventory = []
74 # currently selected tool (item) 74 # currently selected tool (item)
75 self.tool = None 75 self.tool = None
76 # Global game data
77 self.data = {}
76 # current scene 78 # current scene
77 self.current_scene = None 79 self.current_scene = None
78 # current detail view 80 # current detail view
79 self.current_detail = None 81 self.current_detail = None
80 # scene we came from, for enter and leave processing 82 # scene we came from, for enter and leave processing
90 92
91 def set_debug_rects(self, value=True): 93 def set_debug_rects(self, value=True):
92 self.debug_rects = value 94 self.debug_rects = value
93 95
94 def add_scene(self, scene): 96 def add_scene(self, scene):
95 scene.set_state(self) 97 scene.set_game(self)
96 self.scenes[scene.name] = scene 98 self.scenes[scene.name] = scene
97 99
98 def add_detail_view(self, detail_view): 100 def add_detail_view(self, detail_view):
99 detail_view.set_state(self) 101 detail_view.set_game(self)
100 self.detail_views[detail_view.name] = detail_view 102 self.detail_views[detail_view.name] = detail_view
101 103
102 def add_item(self, item): 104 def add_item(self, item):
103 item.set_state(self) 105 item.set_game(self)
104 self.items[item.name] = item 106 self.items[item.name] = item
105 107
106 def load_scenes(self, modname): 108 def load_scenes(self, modname):
107 mod = __import__("gamelib.scenes.%s" % (modname,), fromlist=[modname]) 109 mod = __import__("gamelib.scenes.%s" % (modname,), fromlist=[modname])
108 for scene_cls in mod.SCENES: 110 for scene_cls in mod.SCENES:
203 class GameDeveloperGizmo(object): 205 class GameDeveloperGizmo(object):
204 """Base class for objects game developers see.""" 206 """Base class for objects game developers see."""
205 207
206 def __init__(self): 208 def __init__(self):
207 """Set """ 209 """Set """
208 self.state = None 210 self.game = None
209 self.gd = None 211 self.gd = None
210 self.resource = None 212 self.resource = None
211 self.sound = None 213 self.sound = None
212 214
213 def set_state(self, state): 215 def set_game(self, game):
214 self.state = state 216 self.game = game
215 self.gd = state.gd 217 self.gd = game.gd
216 self.resource = self.gd.resource 218 self.resource = self.gd.resource
217 self.sound = self.gd.sound 219 self.sound = self.gd.sound
218 self.setup() 220 self.setup()
219 221
220 def setup(self): 222 def setup(self):
228 230
229 class StatefulGizmo(GameDeveloperGizmo): 231 class StatefulGizmo(GameDeveloperGizmo):
230 232
231 # initial data (optional, defaults to none) 233 # initial data (optional, defaults to none)
232 INITIAL_DATA = None 234 INITIAL_DATA = None
235 STATE_KEY = None
233 236
234 def __init__(self): 237 def __init__(self):
235 GameDeveloperGizmo.__init__(self) 238 GameDeveloperGizmo.__init__(self)
236 self.data = {} 239 self.state_key = self.STATE_KEY
237 if self.INITIAL_DATA: 240 self.state = None # set this with set_state if required
238 # deep copy of INITIAL_DATA allows lists, sets and 241
239 # other mutable types to safely be used in INITIAL_DATA 242 def set_state(self, state):
240 self.data.update(copy.deepcopy(self.INITIAL_DATA)) 243 """Set the state object and initialize if needed"""
244 self.state = state
245 if self.state_key not in self.state:
246 self.state[self.state_key] = {}
247 if self.INITIAL_DATA:
248 # deep copy of INITIAL_DATA allows lists, sets and
249 # other mutable types to safely be used in INITIAL_DATA
250 self.state[self.state_key].update(
251 copy.deepcopy(self.INITIAL_DATA))
241 252
242 def set_data(self, key, value): 253 def set_data(self, key, value):
243 self.data[key] = value 254 if self.state:
255 self.state[self.state_key][key] = value
244 256
245 def get_data(self, key): 257 def get_data(self, key):
246 return self.data.get(key, None) 258 if self.state:
259 return self.state[self.state_key].get(key, None)
247 260
248 261
249 class Scene(StatefulGizmo): 262 class Scene(StatefulGizmo):
250 """Base class for scenes.""" 263 """Base class for scenes."""
251 264
263 276
264 def __init__(self, state): 277 def __init__(self, state):
265 StatefulGizmo.__init__(self) 278 StatefulGizmo.__init__(self)
266 # scene name 279 # scene name
267 self.name = self.NAME if self.NAME is not None else self.FOLDER 280 self.name = self.NAME if self.NAME is not None else self.FOLDER
281 self.state_key = self.name
268 # map of thing names -> Thing objects 282 # map of thing names -> Thing objects
269 self.things = {} 283 self.things = {}
270 self._background = None 284 self._background = None
271 285
286 def set_game(self, game):
287 super(Scene, self).set_game(game)
288 self.set_state(game.data)
289
272 def add_item(self, item): 290 def add_item(self, item):
273 self.state.add_item(item) 291 self.game.add_item(item)
274 292
275 def add_thing(self, thing): 293 def add_thing(self, thing):
276 self.things[thing.name] = thing 294 self.things[thing.name] = thing
277 thing.set_state(self.state) 295 thing.set_game(self.game)
278 thing.set_scene(self) 296 thing.set_scene(self)
279 297
280 def remove_thing(self, thing): 298 def remove_thing(self, thing):
281 del self.things[thing.name] 299 del self.things[thing.name]
282 if thing is self.state.current_thing: 300 if thing is self.game.current_thing:
283 self.state.current_thing.leave() 301 self.game.current_thing.leave()
284 self.state.current_thing = None 302 self.game.current_thing = None
285 303
286 def _get_description(self): 304 def _get_description(self):
287 text = (self.state.current_thing and 305 text = (self.game.current_thing and
288 self.state.current_thing.get_description()) 306 self.game.current_thing.get_description())
289 if text is None: 307 if text is None:
290 return None 308 return None
291 label = BoomLabel(text) 309 label = BoomLabel(text)
292 label.set_margin(5) 310 label.set_margin(5)
293 label.border_width = 1 311 label.border_width = 1
330 348
331 Item may be an item in the list of items or None for the hand. 349 Item may be an item in the list of items or None for the hand.
332 350
333 Returns a Result object to provide feedback to the player. 351 Returns a Result object to provide feedback to the player.
334 """ 352 """
335 if self.state.current_thing is not None: 353 if self.game.current_thing is not None:
336 return self.state.current_thing.interact(item) 354 return self.game.current_thing.interact(item)
337 355
338 def animate(self): 356 def animate(self):
339 """Animate all the things in the scene. 357 """Animate all the things in the scene.
340 358
341 Return true if any of them need to queue a redraw""" 359 Return true if any of them need to queue a redraw"""
350 368
351 def leave(self): 369 def leave(self):
352 return None 370 return None
353 371
354 def update_current_thing(self, pos): 372 def update_current_thing(self, pos):
355 if self.state.current_thing is not None: 373 if self.game.current_thing is not None:
356 if not self.state.current_thing.contains(pos): 374 if not self.game.current_thing.contains(pos):
357 self.state.current_thing.leave() 375 self.game.current_thing.leave()
358 self.state.current_thing = None 376 self.game.current_thing = None
359 for thing in self.things.itervalues(): 377 for thing in self.things.itervalues():
360 if thing.contains(pos): 378 if thing.contains(pos):
361 thing.enter(self.state.tool) 379 thing.enter(self.game.tool)
362 self.state.current_thing = thing 380 self.game.current_thing = thing
363 break 381 break
364 382
365 def mouse_move(self, pos): 383 def mouse_move(self, pos):
366 """Call to check whether the cursor has entered / exited a thing. 384 """Call to check whether the cursor has entered / exited a thing.
367 385
428 StatefulGizmo.__init__(self) 446 StatefulGizmo.__init__(self)
429 # name of the thing 447 # name of the thing
430 self.name = self.NAME 448 self.name = self.NAME
431 # folder for resource (None is overridden by scene folder) 449 # folder for resource (None is overridden by scene folder)
432 self.folder = self.FOLDER 450 self.folder = self.FOLDER
451 self.state_key = self.NAME
433 # interacts 452 # interacts
434 self.interacts = self.INTERACTS 453 self.interacts = self.INTERACTS
435 # these are set by set_scene 454 # these are set by set_scene
436 self.scene = None 455 self.scene = None
437 self.current_interact = None 456 self.current_interact = None
451 def set_scene(self, scene): 470 def set_scene(self, scene):
452 assert self.scene is None 471 assert self.scene is None
453 self.scene = scene 472 self.scene = scene
454 if self.folder is None: 473 if self.folder is None:
455 self.folder = scene.FOLDER 474 self.folder = scene.FOLDER
456 self.state = scene.state 475 self.game = scene.game
476 self.set_state(self.game.data)
457 for interact in self.interacts.itervalues(): 477 for interact in self.interacts.itervalues():
458 interact.set_thing(self) 478 interact.set_thing(self)
459 self.set_interact(self.INITIAL) 479 self.set_interact(self.INITIAL)
460 480
461 def set_interact(self, name): 481 def set_interact(self, name):
493 old_rect = self.current_interact.rect 513 old_rect = self.current_interact.rect
494 if old_rect: 514 if old_rect:
495 self.current_interact.rect = old_rect.move(self.scene.OFFSET) 515 self.current_interact.rect = old_rect.move(self.scene.OFFSET)
496 self.current_interact.draw(surface) 516 self.current_interact.draw(surface)
497 self.current_interact.rect = old_rect 517 self.current_interact.rect = old_rect
498 if self.state.debug_rects and self._interact_hilight_color: 518 if self.game.debug_rects and self._interact_hilight_color:
499 if hasattr(self.rect, 'collidepoint'): 519 if hasattr(self.rect, 'collidepoint'):
500 frame_rect(surface, self._interact_hilight_color, 520 frame_rect(surface, self._interact_hilight_color,
501 self.rect.inflate(1, 1), 1) 521 self.rect.inflate(1, 1), 1)
502 else: 522 else:
503 for rect in self.rect: 523 for rect in self.rect: