annotate skaapsteker/engine.py @ 249:30ae3c681507

Doors and stuff.
author Jeremy Thurgood <firxen@gmail.com>
date Thu, 07 Apr 2011 22:20:58 +0200
parents 129afb4417cf
children 8d7edd77bfbf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
1 """Top-level engine for switching scenes."""
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
2
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
3 import pygame.display
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
4 import pygame.time
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
5 import pygame.event
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
6 from pygame.locals import QUIT, USEREVENT
11
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
7
248
129afb4417cf Some light cleanup.
Jeremy Thurgood <firxen@gmail.com>
parents: 244
diff changeset
8 from .gamestate import GameState
127
e1dd3b785269 Initial game state stuff.
Jeremy Thurgood <firxen@gmail.com>
parents: 126
diff changeset
9
11
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
10 class Engine(object):
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
11
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
12 def __init__(self):
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
13 self._framerate = 60
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
14 self._current_scene = None
123
592477d8b09b Add fps to game
Neil Muller <drnlmuller@gmail.com>
parents: 79
diff changeset
15 self._fpss = [self._framerate] * 100
592477d8b09b Add fps to game
Neil Muller <drnlmuller@gmail.com>
parents: 79
diff changeset
16 self._cur_frame = 0
189
9d08f99b5ddf Add npcs to gamestate. Update gamestate. Pass world around a bit. Some other stuff.
Simon Cross <hodgestar@gmail.com>
parents: 165
diff changeset
17 self.game_state = GameState("game.json")
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
18
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
19 def change_scene(self, next_scene):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
20 if self._current_scene is not None:
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
21 self._current_scene.leave()
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
22 self._current_scene = next_scene
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
23 self._current_scene.enter()
11
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
24
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
25 def run(self):
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
26 """Run the game loop dispatching events as necessary."""
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
27 assert self._current_scene is not None
11
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
28 clock = pygame.time.Clock()
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
29 surface = pygame.display.get_surface()
11
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
30 while True:
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
31 events = pygame.event.get()
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
32 for ev in events:
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
33 if ev.type is QUIT:
249814efa91b Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
34 return
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
35 if ChangeScene.matches(ev):
249
30ae3c681507 Doors and stuff.
Jeremy Thurgood <firxen@gmail.com>
parents: 248
diff changeset
36 next_scene = ev.next_scene
30ae3c681507 Doors and stuff.
Jeremy Thurgood <firxen@gmail.com>
parents: 248
diff changeset
37 if not isinstance(next_scene, Scene):
30ae3c681507 Doors and stuff.
Jeremy Thurgood <firxen@gmail.com>
parents: 248
diff changeset
38 next_scene = next_scene[0](self.game_state, *(next_scene[1:]))
30ae3c681507 Doors and stuff.
Jeremy Thurgood <firxen@gmail.com>
parents: 248
diff changeset
39 self.change_scene(next_scene)
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
40 break
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
41 self._current_scene.dispatch(ev)
123
592477d8b09b Add fps to game
Neil Muller <drnlmuller@gmail.com>
parents: 79
diff changeset
42 self._current_scene.draw(surface, self)
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
43 pygame.display.flip()
126
9cae256b91d7 Fix bug in FPS calculation. Phew -- we're still fast.
Simon Cross <hodgestar@gmail.com>
parents: 123
diff changeset
44 self._fpss[self._cur_frame] = 1000.0 / clock.tick(self._framerate)
123
592477d8b09b Add fps to game
Neil Muller <drnlmuller@gmail.com>
parents: 79
diff changeset
45 self._cur_frame = self._cur_frame + 1 if self._cur_frame < 99 else 0
592477d8b09b Add fps to game
Neil Muller <drnlmuller@gmail.com>
parents: 79
diff changeset
46
592477d8b09b Add fps to game
Neil Muller <drnlmuller@gmail.com>
parents: 79
diff changeset
47 def get_fps(self):
592477d8b09b Add fps to game
Neil Muller <drnlmuller@gmail.com>
parents: 79
diff changeset
48 return sum(self._fpss) / 100
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
49
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
50
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
51 class Scene(object):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
52
127
e1dd3b785269 Initial game state stuff.
Jeremy Thurgood <firxen@gmail.com>
parents: 126
diff changeset
53 def __init__(self, game_state):
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 14
diff changeset
54 self.widgets = []
165
8d45715c587d Rename ._game_state to game_state for consistency with engine and since everyone and their dog has access to it. :)
Simon Cross <hodgestar@gmail.com>
parents: 133
diff changeset
55 self.game_state = game_state
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
56
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
57 def post(self, ev):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
58 """Post an event to pygame's event loop."""
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
59 pygame.event.post(ev)
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
60
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
61 def enter(self):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
62 """Enter the scene."""
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
63 pass
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
64
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
65 def leave(self):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
66 """Exit the scene."""
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
67 pass
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
68
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
69 def dispatch(self, ev):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
70 """Dispatch an event."""
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 14
diff changeset
71 for widget in self.widgets:
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 14
diff changeset
72 widget.dispatch(ev)
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
73
133
aca8b7456c72 Pass engine to all Scene draw() methods
Stefano Rivera <stefano@rivera.za.net>
parents: 127
diff changeset
74 def draw(self, surface, engine):
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
75 """Update the scene surface."""
79
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 14
diff changeset
76 for widget in self.widgets:
fe8652a060df Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents: 14
diff changeset
77 widget.draw(surface)
14
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
78
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
79
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
80 class UserEvent(object):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
81
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
82 utype = "UNKNOWN"
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
83
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
84 @classmethod
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
85 def post(cls, **kws):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
86 ev = pygame.event.Event(USEREVENT, utype=cls.utype, **kws)
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
87 pygame.event.post(ev)
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
88
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
89 @classmethod
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
90 def matches(cls, ev):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
91 return ev.type is USEREVENT and ev.utype == cls.utype
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
92
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
93 class ChangeScene(UserEvent):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
94
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
95 utype = "CHANGE_SCENE"
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
96
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
97 @classmethod
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
98 def post(cls, next_scene):
fb1bd081cc86 Add scene changing.
Simon Cross <hodgestar@gmail.com>
parents: 11
diff changeset
99 super(ChangeScene, cls).post(next_scene=next_scene)
244
5bbf90e6a94b Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents: 189
diff changeset
100
5bbf90e6a94b Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents: 189
diff changeset
101 class PlayerDied(UserEvent):
5bbf90e6a94b Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents: 189
diff changeset
102
5bbf90e6a94b Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents: 189
diff changeset
103 utype = "PLAYER_DIED"
5bbf90e6a94b Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents: 189
diff changeset
104
5bbf90e6a94b Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents: 189
diff changeset
105 @classmethod
5bbf90e6a94b Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents: 189
diff changeset
106 def post(cls):
5bbf90e6a94b Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents: 189
diff changeset
107 super(PlayerDied, cls).post()