diff 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
line wrap: on
line diff
--- a/demos/shooter/scripts/scene.py	Thu Apr 22 01:18:44 2010 +0000
+++ b/demos/shooter/scripts/scene.py	Thu Apr 22 19:52:34 2010 +0000
@@ -22,7 +22,7 @@
 # ####################################################################
 
 from fife import fife
-from scripts.ships.shipbase import Ship
+from scripts.ships.shipbase import *
 from scripts.ships.player import Player
 from scripts.ships.enemies import *
 from scripts.common.helpers import Rect
@@ -68,8 +68,6 @@
 		self._timemod = 0
 		
 		self._gameover = False
-		
-		self._boss = None
 
 	def destroyScene(self):
 		nodestodelete = list()
@@ -97,8 +95,6 @@
 		for i in range(0,self._maxnodes):
 			self._nodes.append(SceneNode())
 
-		self._boss = None
-
 		self._player = Player(self, 'player')
 		self._player.init()
 		self._player.start()
@@ -139,7 +135,6 @@
 				enemy = Streaker(self, 'enemy', instance, False)
 			elif objectName == "boss":
 				enemy = Boss(self, 'enemy', instance, False)
-				self._boss = enemy
 			else:
 				enemy = Ship(self, 'enemy', instance, False)
 				
@@ -202,30 +197,35 @@
 		loc = obj.instance.getLocation().getExactLayerCoordinates()
 		nodeindex = int(loc.x * self._xscale)
 
-		obj.scenenodeid = nodeindex		
-		self._nodes[nodeindex].spaceobjects.append(obj)
-
-	def addProjectileToScene(self, projectile):
-		self._projectiles.append(projectile)
+		if nodeindex >= 0:
+			obj.scenenodeid = nodeindex
+			self._nodes[nodeindex].spaceobjects.append(obj)
+		else:
+			self.queueObjectForRemoval(obj)
 	
 	def moveObjectInScene(self, obj):
 		loc = obj.instance.getLocation().getExactLayerCoordinates()
 		nodeindex = int(loc.x * self._xscale)
 		
-		if nodeindex != obj.scenenodeid:
-			if obj in self._nodes[obj.scenenodeid].spaceobjects:
-				self._nodes[obj.scenenodeid].spaceobjects.remove(obj)
+		if nodeindex >= 0:
+			if nodeindex != obj.scenenodeid:
+				if obj in self._nodes[obj.scenenodeid].spaceobjects:
+					self._nodes[obj.scenenodeid].spaceobjects.remove(obj)
 
-			obj.scenenodeid = nodeindex
-			self._nodes[nodeindex].spaceobjects.append(obj)
+				self._nodes[nodeindex].spaceobjects.append(obj)
+			
+				obj.scenenodeid = nodeindex
+		else:
+			self.queueObjectForRemoval(obj)
 
 	def removeObjectFromScene(self, obj):
 		for node in self._nodes:
 			if obj in node.spaceobjects:
+				if obj.instance:
+					self._layer.deleteInstance(obj.instance)
+					obj.instance = None
 				node.spaceobjects.remove(obj)
-				self._layer.deleteInstance(obj.instance)
-				obj.instance = None
-				return
+				break
 	
 	def attachCamera(self, cam):
 		self._camera = cam
@@ -244,6 +244,13 @@
 		
 		self._keystate = keystate
 		
+		
+		#some garbage cleanup
+		for obj in self._objectstodelete:
+			self.removeObjectFromScene(obj)
+					
+		self._objectstodelete = list()
+		
 		#update camera location
 		loc = self._camera.getLocation()
 		exactloc = self._camera.getLocation().getExactLayerCoordinates()
@@ -268,17 +275,17 @@
 
 		#update objects on the screen
 		for obj in screenlist:
-			if obj == self._boss:
-				if bottomright.x > ((self._boss.location.getExactLayerCoordinates().x * self._xscale) + 0.5):
+			if obj.type == SHTR_LASTBOSS:
+				if bottomright.x > ((obj.location.getExactLayerCoordinates().x * self._xscale) + 0.5):
 					self.stopCamera()
 
-			if not (obj == self._player and self._gameover):
+			if not (obj.type == SHTR_PLAYER and self._gameover):
 				obj.update()
 			
 			if obj.changedposition:
 				self.moveObjectInScene(obj)
 
-			if obj != self._player:
+			if obj.type != SHTR_PLAYER and obj.type != SHTR_PROJECTILE:
 				if obj.running and obj.boundingbox.intersects(self._player.boundingbox):
 					#player touched an enemy.  Destroy player and 
 					#re-initialize scene
@@ -286,51 +293,34 @@
 						#collision damage of 1
 						self.playerHit(1)
 						obj.applyHit(1)
-						
-#			self._world.renderBoundingBox(obj)
-					
-		
-		
-		#update the list of projectiles
-		projtodelete = list()
-		for p in self._projectiles:
-			p.update()
-			#check to see if the projectile hit any object on the screen
-			for o in screenlist:
-				#cant get hit by your own bullet
-				if p.owner != o:
-					if o.running and p.boundingbox.intersects(o.boundingbox):
-						if o != self._player and p.owner.isplayer:
-							o.applyHit(p.damage)
-							#check if enemy ship was destroyed
-							if not o.running:
-								self._player.applyScore(o.scorevalue)
-							p.destroy()
-						elif o == self._player:
-							#player got hit by a projectile
-							if not self._player.invulnerable:
-								self.playerHit(p.damage)
-								p.destroy()
+
+			elif obj.type == SHTR_PROJECTILE:
+				#could probably just get the nodes in the projectiles scenenode.
+				#use a range to be sure.
+				pcollide = self.getObjectsInRange(obj.scenenodeid - 1, obj.scenenodeid + 1)
+				
+				for o in pcollide:
+					#cant get hit by your own bullet
+					if obj.owner != o and o.type != SHTR_PROJECTILE:
+						if o.running and obj.boundingbox.intersects(o.boundingbox):
+							if o != self._player and obj.owner.type == SHTR_PLAYER:
+								o.applyHit(obj.damage)
+								#check if enemy ship was destroyed
+								if not o.running:
+									self._player.applyScore(o.scorevalue)
+								obj.destroy()
+							elif o == self._player:
+								#player got hit by a projectile
+								if not self._player.invulnerable:
+									self.playerHit(obj.damage)
+									obj.destroy()
 			
-#			self._world.renderBoundingBox(p)
-							
-			
-			#build a list of projectiles to remove (ttl expired)
-			if not p.running:
-				projtodelete.append(p)
+				#queue list of projectiles to remove (ttl expired or has been destroyed)
+				if not obj.running:
+					self.queueObjectForRemoval(obj)
 
-		#remove any expired projectiles 
-		for p in projtodelete:
-			if p in self._projectiles:
-				p.destroy()
-				self._projectiles.remove(p)
-		
-		for obj in self._objectstodelete:
-			self.removeObjectFromScene(obj)
-			self._layer.deleteInstance(obj.instance)
-			obj.instance = None
-			
-		self._objectstodelete = list()
+#			self._world.renderBoundingBox(obj)			
+
 
 				
 	def _getPlayer(self):