Mercurial > skaapsteker
annotate skaapsteker/engine.py @ 250:8d7edd77bfbf
Start hooking up NPC interactions.
author | Simon Cross <hodgestar@gmail.com> |
---|---|
date | Thu, 07 Apr 2011 23:57:22 +0200 |
parents | 30ae3c681507 |
children | de60329cfc9f |
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 | 6 from pygame.locals import QUIT, USEREVENT |
11
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
7 |
127
e1dd3b785269
Initial game state stuff.
Jeremy Thurgood <firxen@gmail.com>
parents:
126
diff
changeset
|
8 |
11
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
9 class Engine(object): |
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
10 |
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
11 def __init__(self): |
250
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
12 # avoid circular imports |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
13 from .gamestate import GameState |
11
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
14 self._framerate = 60 |
14 | 15 self._current_scene = None |
123 | 16 self._fpss = [self._framerate] * 100 |
17 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
|
18 self.game_state = GameState("game.json") |
14 | 19 |
20 def change_scene(self, next_scene): | |
21 if self._current_scene is not None: | |
22 self._current_scene.leave() | |
23 self._current_scene = next_scene | |
24 self._current_scene.enter() | |
11
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
25 |
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
26 def run(self): |
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
27 """Run the game loop dispatching events as necessary.""" |
14 | 28 assert self._current_scene is not None |
11
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
29 clock = pygame.time.Clock() |
14 | 30 surface = pygame.display.get_surface() |
11
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
31 while True: |
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
32 events = pygame.event.get() |
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
33 for ev in events: |
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
34 if ev.type is QUIT: |
249814efa91b
Create game engine. Enable quitting.
Simon Cross <hodgestar@gmail.com>
parents:
diff
changeset
|
35 return |
14 | 36 if ChangeScene.matches(ev): |
249 | 37 next_scene = ev.next_scene |
38 if not isinstance(next_scene, Scene): | |
39 next_scene = next_scene[0](self.game_state, *(next_scene[1:])) | |
40 self.change_scene(next_scene) | |
14 | 41 break |
42 self._current_scene.dispatch(ev) | |
123 | 43 self._current_scene.draw(surface, self) |
14 | 44 pygame.display.flip() |
126
9cae256b91d7
Fix bug in FPS calculation. Phew -- we're still fast.
Simon Cross <hodgestar@gmail.com>
parents:
123
diff
changeset
|
45 self._fpss[self._cur_frame] = 1000.0 / clock.tick(self._framerate) |
123 | 46 self._cur_frame = self._cur_frame + 1 if self._cur_frame < 99 else 0 |
47 | |
48 def get_fps(self): | |
49 return sum(self._fpss) / 100 | |
14 | 50 |
51 | |
52 class Scene(object): | |
53 | |
127
e1dd3b785269
Initial game state stuff.
Jeremy Thurgood <firxen@gmail.com>
parents:
126
diff
changeset
|
54 def __init__(self, game_state): |
79
fe8652a060df
Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents:
14
diff
changeset
|
55 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
|
56 self.game_state = game_state |
14 | 57 |
58 def post(self, ev): | |
59 """Post an event to pygame's event loop.""" | |
60 pygame.event.post(ev) | |
61 | |
62 def enter(self): | |
63 """Enter the scene.""" | |
64 pass | |
65 | |
66 def leave(self): | |
67 """Exit the scene.""" | |
68 pass | |
69 | |
70 def dispatch(self, ev): | |
71 """Dispatch an event.""" | |
79
fe8652a060df
Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents:
14
diff
changeset
|
72 for widget in self.widgets: |
fe8652a060df
Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents:
14
diff
changeset
|
73 widget.dispatch(ev) |
14 | 74 |
133
aca8b7456c72
Pass engine to all Scene draw() methods
Stefano Rivera <stefano@rivera.za.net>
parents:
127
diff
changeset
|
75 def draw(self, surface, engine): |
14 | 76 """Update the scene surface.""" |
79
fe8652a060df
Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents:
14
diff
changeset
|
77 for widget in self.widgets: |
fe8652a060df
Simple menu screen and TextChoice widget
Stefano Rivera <stefano@rivera.za.net>
parents:
14
diff
changeset
|
78 widget.draw(surface) |
14 | 79 |
80 | |
81 class UserEvent(object): | |
82 | |
83 utype = "UNKNOWN" | |
84 | |
85 @classmethod | |
86 def post(cls, **kws): | |
87 ev = pygame.event.Event(USEREVENT, utype=cls.utype, **kws) | |
88 pygame.event.post(ev) | |
89 | |
90 @classmethod | |
91 def matches(cls, ev): | |
92 return ev.type is USEREVENT and ev.utype == cls.utype | |
93 | |
94 class ChangeScene(UserEvent): | |
95 | |
96 utype = "CHANGE_SCENE" | |
97 | |
98 @classmethod | |
99 def post(cls, next_scene): | |
100 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
|
101 |
5bbf90e6a94b
Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents:
189
diff
changeset
|
102 class PlayerDied(UserEvent): |
5bbf90e6a94b
Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents:
189
diff
changeset
|
103 |
5bbf90e6a94b
Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents:
189
diff
changeset
|
104 utype = "PLAYER_DIED" |
5bbf90e6a94b
Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents:
189
diff
changeset
|
105 |
5bbf90e6a94b
Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents:
189
diff
changeset
|
106 @classmethod |
5bbf90e6a94b
Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents:
189
diff
changeset
|
107 def post(cls): |
5bbf90e6a94b
Add minimal support for player death
Neil Muller <drnlmuller@gmail.com>
parents:
189
diff
changeset
|
108 super(PlayerDied, cls).post() |
250
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
109 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
110 class OpenDialog(UserEvent): |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
111 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
112 utype = "OPEN_DIALOG" |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
113 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
114 @classmethod |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
115 def post(cls, npc): |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
116 # request to open dialog box for given NPC sprite |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
117 # will do nothing if the NPC's current state has |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
118 # no text |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
119 super(OpenDialog, cls).post(npc=npc) |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
120 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
121 class CloseDialog(UserEvent): |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
122 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
123 utype = "CLOSE_DIALOG" |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
124 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
125 @classmethod |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
126 def post(cls, npc): |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
127 # close dialog box for given NPC sprite |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
128 # will do nothing if the sprite has no dialog open |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
129 super(CloseDialog, cls).post(npc=npc) |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
130 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
131 class NpcEvent(UserEvent): # TODO: Needed? |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
132 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
133 utype = "NPC_EVENT" |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
134 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
135 @classmethod |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
136 def post(cls, npc, ev): |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
137 """npc is an NPC sprite. |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
138 ev is a DsmEvent for that sprite. |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
139 """ |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
140 super(NpcEvent, cls).post(npc=npc, ev=ev) |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
141 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
142 class GlobalNpcEvent(UserEvent): # TODO: Needed? |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
143 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
144 utype = "GLOBAL_NPC_EVENT" |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
145 |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
146 @classmethod |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
147 def post(cls, ev): |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
148 """Send a DsmEvent event to all NPCs. |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
149 """ |
8d7edd77bfbf
Start hooking up NPC interactions.
Simon Cross <hodgestar@gmail.com>
parents:
249
diff
changeset
|
150 super(GlobalNpcEvent, cls).post(ev=ev) |