Mercurial > fife-parpg
comparison demos/shooter/scripts/scene.py @ 477:6b33d80b468b
Projectiles are now part of the scene.
Cleaned up the scene update() function.
Moved garbage collection to the beginning of the frame.
Introduced global object types.
Projectiles now only check for collisions in a limited number of scene nodes rather than the entire screen.
author | prock@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Thu, 22 Apr 2010 19:52:34 +0000 |
parents | 78a1eb57c074 |
children | 41f7754f2a4b |
comparison
equal
deleted
inserted
replaced
476:78a1eb57c074 | 477:6b33d80b468b |
---|---|
20 # Free Software Foundation, Inc., | 20 # Free Software Foundation, Inc., |
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 # #################################################################### | 22 # #################################################################### |
23 | 23 |
24 from fife import fife | 24 from fife import fife |
25 from scripts.ships.shipbase import Ship | 25 from scripts.ships.shipbase import * |
26 from scripts.ships.player import Player | 26 from scripts.ships.player import Player |
27 from scripts.ships.enemies import * | 27 from scripts.ships.enemies import * |
28 from scripts.common.helpers import Rect | 28 from scripts.common.helpers import Rect |
29 | 29 |
30 class SceneNode(object): | 30 class SceneNode(object): |
66 | 66 |
67 self._paused = False | 67 self._paused = False |
68 self._timemod = 0 | 68 self._timemod = 0 |
69 | 69 |
70 self._gameover = False | 70 self._gameover = False |
71 | |
72 self._boss = None | |
73 | 71 |
74 def destroyScene(self): | 72 def destroyScene(self): |
75 nodestodelete = list() | 73 nodestodelete = list() |
76 objtodelete = list() | 74 objtodelete = list() |
77 | 75 |
94 | 92 |
95 def initScene(self, mapobj): | 93 def initScene(self, mapobj): |
96 #initialize our scene array to some arbitrary size | 94 #initialize our scene array to some arbitrary size |
97 for i in range(0,self._maxnodes): | 95 for i in range(0,self._maxnodes): |
98 self._nodes.append(SceneNode()) | 96 self._nodes.append(SceneNode()) |
99 | |
100 self._boss = None | |
101 | 97 |
102 self._player = Player(self, 'player') | 98 self._player = Player(self, 'player') |
103 self._player.init() | 99 self._player.init() |
104 self._player.start() | 100 self._player.start() |
105 | 101 |
137 enemy = DiagSaucer(self, 'enemy', 1, instance, False) | 133 enemy = DiagSaucer(self, 'enemy', 1, instance, False) |
138 elif objectName == "streaker": | 134 elif objectName == "streaker": |
139 enemy = Streaker(self, 'enemy', instance, False) | 135 enemy = Streaker(self, 'enemy', instance, False) |
140 elif objectName == "boss": | 136 elif objectName == "boss": |
141 enemy = Boss(self, 'enemy', instance, False) | 137 enemy = Boss(self, 'enemy', instance, False) |
142 self._boss = enemy | |
143 else: | 138 else: |
144 enemy = Ship(self, 'enemy', instance, False) | 139 enemy = Ship(self, 'enemy', instance, False) |
145 | 140 |
146 enemy.start() | 141 enemy.start() |
147 | 142 |
200 def addObjectToScene(self, obj): | 195 def addObjectToScene(self, obj): |
201 #TODO: search to ensure the object isn't already part of the scene | 196 #TODO: search to ensure the object isn't already part of the scene |
202 loc = obj.instance.getLocation().getExactLayerCoordinates() | 197 loc = obj.instance.getLocation().getExactLayerCoordinates() |
203 nodeindex = int(loc.x * self._xscale) | 198 nodeindex = int(loc.x * self._xscale) |
204 | 199 |
205 obj.scenenodeid = nodeindex | 200 if nodeindex >= 0: |
206 self._nodes[nodeindex].spaceobjects.append(obj) | 201 obj.scenenodeid = nodeindex |
207 | 202 self._nodes[nodeindex].spaceobjects.append(obj) |
208 def addProjectileToScene(self, projectile): | 203 else: |
209 self._projectiles.append(projectile) | 204 self.queueObjectForRemoval(obj) |
210 | 205 |
211 def moveObjectInScene(self, obj): | 206 def moveObjectInScene(self, obj): |
212 loc = obj.instance.getLocation().getExactLayerCoordinates() | 207 loc = obj.instance.getLocation().getExactLayerCoordinates() |
213 nodeindex = int(loc.x * self._xscale) | 208 nodeindex = int(loc.x * self._xscale) |
214 | 209 |
215 if nodeindex != obj.scenenodeid: | 210 if nodeindex >= 0: |
216 if obj in self._nodes[obj.scenenodeid].spaceobjects: | 211 if nodeindex != obj.scenenodeid: |
217 self._nodes[obj.scenenodeid].spaceobjects.remove(obj) | 212 if obj in self._nodes[obj.scenenodeid].spaceobjects: |
218 | 213 self._nodes[obj.scenenodeid].spaceobjects.remove(obj) |
219 obj.scenenodeid = nodeindex | 214 |
220 self._nodes[nodeindex].spaceobjects.append(obj) | 215 self._nodes[nodeindex].spaceobjects.append(obj) |
216 | |
217 obj.scenenodeid = nodeindex | |
218 else: | |
219 self.queueObjectForRemoval(obj) | |
221 | 220 |
222 def removeObjectFromScene(self, obj): | 221 def removeObjectFromScene(self, obj): |
223 for node in self._nodes: | 222 for node in self._nodes: |
224 if obj in node.spaceobjects: | 223 if obj in node.spaceobjects: |
224 if obj.instance: | |
225 self._layer.deleteInstance(obj.instance) | |
226 obj.instance = None | |
225 node.spaceobjects.remove(obj) | 227 node.spaceobjects.remove(obj) |
226 self._layer.deleteInstance(obj.instance) | 228 break |
227 obj.instance = None | |
228 return | |
229 | 229 |
230 def attachCamera(self, cam): | 230 def attachCamera(self, cam): |
231 self._camera = cam | 231 self._camera = cam |
232 self._camera.setLocation(self._player.location) | 232 self._camera.setLocation(self._player.location) |
233 | 233 |
241 timedelta = (time - self._timemod) - self._time | 241 timedelta = (time - self._timemod) - self._time |
242 self._timedelta = timedelta | 242 self._timedelta = timedelta |
243 self._time = time - self._timemod | 243 self._time = time - self._timemod |
244 | 244 |
245 self._keystate = keystate | 245 self._keystate = keystate |
246 | |
247 | |
248 #some garbage cleanup | |
249 for obj in self._objectstodelete: | |
250 self.removeObjectFromScene(obj) | |
251 | |
252 self._objectstodelete = list() | |
246 | 253 |
247 #update camera location | 254 #update camera location |
248 loc = self._camera.getLocation() | 255 loc = self._camera.getLocation() |
249 exactloc = self._camera.getLocation().getExactLayerCoordinates() | 256 exactloc = self._camera.getLocation().getExactLayerCoordinates() |
250 #slowly move to the right | 257 #slowly move to the right |
266 rightnode = self._maxnodes | 273 rightnode = self._maxnodes |
267 screenlist = self.getObjectsInRange(leftnode, rightnode) | 274 screenlist = self.getObjectsInRange(leftnode, rightnode) |
268 | 275 |
269 #update objects on the screen | 276 #update objects on the screen |
270 for obj in screenlist: | 277 for obj in screenlist: |
271 if obj == self._boss: | 278 if obj.type == SHTR_LASTBOSS: |
272 if bottomright.x > ((self._boss.location.getExactLayerCoordinates().x * self._xscale) + 0.5): | 279 if bottomright.x > ((obj.location.getExactLayerCoordinates().x * self._xscale) + 0.5): |
273 self.stopCamera() | 280 self.stopCamera() |
274 | 281 |
275 if not (obj == self._player and self._gameover): | 282 if not (obj.type == SHTR_PLAYER and self._gameover): |
276 obj.update() | 283 obj.update() |
277 | 284 |
278 if obj.changedposition: | 285 if obj.changedposition: |
279 self.moveObjectInScene(obj) | 286 self.moveObjectInScene(obj) |
280 | 287 |
281 if obj != self._player: | 288 if obj.type != SHTR_PLAYER and obj.type != SHTR_PROJECTILE: |
282 if obj.running and obj.boundingbox.intersects(self._player.boundingbox): | 289 if obj.running and obj.boundingbox.intersects(self._player.boundingbox): |
283 #player touched an enemy. Destroy player and | 290 #player touched an enemy. Destroy player and |
284 #re-initialize scene | 291 #re-initialize scene |
285 if not self._player.invulnerable: | 292 if not self._player.invulnerable: |
286 #collision damage of 1 | 293 #collision damage of 1 |
287 self.playerHit(1) | 294 self.playerHit(1) |
288 obj.applyHit(1) | 295 obj.applyHit(1) |
289 | 296 |
290 # self._world.renderBoundingBox(obj) | 297 elif obj.type == SHTR_PROJECTILE: |
291 | 298 #could probably just get the nodes in the projectiles scenenode. |
292 | 299 #use a range to be sure. |
293 | 300 pcollide = self.getObjectsInRange(obj.scenenodeid - 1, obj.scenenodeid + 1) |
294 #update the list of projectiles | 301 |
295 projtodelete = list() | 302 for o in pcollide: |
296 for p in self._projectiles: | 303 #cant get hit by your own bullet |
297 p.update() | 304 if obj.owner != o and o.type != SHTR_PROJECTILE: |
298 #check to see if the projectile hit any object on the screen | 305 if o.running and obj.boundingbox.intersects(o.boundingbox): |
299 for o in screenlist: | 306 if o != self._player and obj.owner.type == SHTR_PLAYER: |
300 #cant get hit by your own bullet | 307 o.applyHit(obj.damage) |
301 if p.owner != o: | 308 #check if enemy ship was destroyed |
302 if o.running and p.boundingbox.intersects(o.boundingbox): | 309 if not o.running: |
303 if o != self._player and p.owner.isplayer: | 310 self._player.applyScore(o.scorevalue) |
304 o.applyHit(p.damage) | 311 obj.destroy() |
305 #check if enemy ship was destroyed | 312 elif o == self._player: |
306 if not o.running: | 313 #player got hit by a projectile |
307 self._player.applyScore(o.scorevalue) | 314 if not self._player.invulnerable: |
308 p.destroy() | 315 self.playerHit(obj.damage) |
309 elif o == self._player: | 316 obj.destroy() |
310 #player got hit by a projectile | 317 |
311 if not self._player.invulnerable: | 318 #queue list of projectiles to remove (ttl expired or has been destroyed) |
312 self.playerHit(p.damage) | 319 if not obj.running: |
313 p.destroy() | 320 self.queueObjectForRemoval(obj) |
314 | 321 |
315 # self._world.renderBoundingBox(p) | 322 # self._world.renderBoundingBox(obj) |
316 | 323 |
317 | |
318 #build a list of projectiles to remove (ttl expired) | |
319 if not p.running: | |
320 projtodelete.append(p) | |
321 | |
322 #remove any expired projectiles | |
323 for p in projtodelete: | |
324 if p in self._projectiles: | |
325 p.destroy() | |
326 self._projectiles.remove(p) | |
327 | |
328 for obj in self._objectstodelete: | |
329 self.removeObjectFromScene(obj) | |
330 self._layer.deleteInstance(obj.instance) | |
331 obj.instance = None | |
332 | |
333 self._objectstodelete = list() | |
334 | 324 |
335 | 325 |
336 def _getPlayer(self): | 326 def _getPlayer(self): |
337 return self._player | 327 return self._player |
338 | 328 |