changeset 448:5e2ec84902a7

Did a little re-factoring. Introduced the scene graph for collision detection. Changed the time scale to be accurate.
author prock@33b003aa-7bff-0310-803a-e67f0ece8222
date Thu, 01 Apr 2010 17:03:34 +0000
parents 64676ea55472
children 1cf56403347a
files demos/shooter/maps/shooter_map1.xml demos/shooter/scripts/common/baseobject.py demos/shooter/scripts/scene.py demos/shooter/scripts/ships/player.py demos/shooter/scripts/ships/shipbase.py demos/shooter/scripts/weapons.py demos/shooter/scripts/world.py
diffstat 7 files changed, 215 insertions(+), 123 deletions(-) [+]
line wrap: on
line diff
--- a/demos/shooter/maps/shooter_map1.xml	Wed Mar 31 21:13:07 2010 +0000
+++ b/demos/shooter/maps/shooter_map1.xml	Thu Apr 01 17:03:34 2010 +0000
@@ -438,12 +438,12 @@
 	<layer y_scale="0.25" y_offset="0.0" pathing="cell_edges_and_diagonals" grid_type="square" id="objects" rotation="0.0" x_scale="0.25" x_offset="0.0" transparency="0">
 		<instances>
 			<i o="ship1" z="0.0" x="7.0" r="0" y="0.0" id="player"></i>
-			<i r="0" x="20.0" o="saucer1" z="0.0" y="-2.0"></i>
-			<i r="0" x="20.0" o="saucer1" z="0.0" y="1.0"></i>
-			<i r="0" x="20.0" o="saucer1" z="0.0" y="4.0"></i>
-			<i r="0" x="20.0" o="saucer1" z="0.0" y="-5.0"></i>
-			<i r="0" x="26.0" o="saucer2" z="0.0" y="-3.0"></i>
-			<i r="0" x="26.0" o="saucer2" z="0.0" y="2.0"></i>
+			<i r="0" id="enemy" x="20.0" o="saucer1" z="0.0" y="-2.0"></i>
+			<i r="0" id="enemy" x="20.0" o="saucer1" z="0.0" y="1.0"></i>
+			<i r="0" id="enemy" x="20.0" o="saucer1" z="0.0" y="4.0"></i>
+			<i r="0" id="enemy" x="20.0" o="saucer1" z="0.0" y="-5.0"></i>
+			<i r="0" id="enemy" x="26.0" o="saucer2" z="0.0" y="-3.0"></i>
+			<i r="0" id="enemy" x="26.0" o="saucer2" z="0.0" y="2.0"></i>
 		</instances>
 	</layer>
 	<camera ref_cell_height="256" zoom="1" rotation="0.0" ref_layer_id="background" ref_cell_width="256" id="main" tilt="0.0">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/shooter/scripts/common/baseobject.py	Thu Apr 01 17:03:34 2010 +0000
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+
+# ####################################################################
+#  Copyright (C) 2005-2009 by the FIFE team
+#  http://www.fifengine.de
+#  This file is part of FIFE.
+#
+#  FIFE is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the
+#  Free Software Foundation, Inc.,
+#  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+# ####################################################################
+
+from fife import fife
+from scripts.common.helpers import normalize
+
+class SpaceObject(object):
+	def __init__(self, model, name, layer, findInstance=True):
+		self._model = model
+		self._layer = layer
+		self._name = name
+		self._xscale = self._layer.getCellGrid().getXScale()
+		self._yscale = self._layer.getCellGrid().getYScale()		
+		self._velocity = fife.DoublePoint(0,0)
+		self._maxvelocity = 1
+		self._timedelta = 0
+		
+		if findInstance:
+			self._instance = self._layer.getInstance(self._name)
+		else:
+			self._instnace = None
+		
+	def start(self):
+		pass
+
+	def update(self, timedelta):
+		self._timedelta = timedelta
+		
+		shiploc = self.location
+		exactloc = shiploc.getExactLayerCoordinates()
+		
+		exactloc.x += self._velocity.x
+		exactloc.y += self._velocity.y
+				
+		shiploc.setExactLayerCoordinates(exactloc)
+		self.location = shiploc
+	
+	def stop(self):
+		pass
+		
+	def destroy(self):
+		pass
+		
+	def applyThrust(self, vector, timedelta):
+		self._velocity.x += (vector.x * (timedelta/100.0))/self._xscale
+		self._velocity.y += (vector.y * (timedelta/100.0))/self._yscale
+		
+		if self._velocity.length() > self._maxvelocity:
+			norm = normalize(self._velocity)
+			self._velocity.x = norm.x * self._maxvelocity
+			self._velocity.y = norm.y * self._maxvelocity
+		
+	
+	def applyBrake(self, brakingForce, timedelta):
+
+		if self._velocity.length() <= .001:
+			self._velocity.x = 0
+			self._velocity.y = 0			
+			return
+		
+		#first normalize to get a unit vector of the direction we are traveling
+		norm = normalize(self._velocity)
+		if norm.length() == 0:
+			self._velocity.x = 0
+			self._velocity.y = 0
+			return
+			
+		#negate to get opposite direction
+		norm.x = norm.x * -1
+		norm.y = norm.y * -1
+		
+		#apply braking deceleration  
+		norm.x *= brakingForce
+		norm.y *= brakingForce
+		
+		self._velocity.x += (norm.x * (timedelta/100.0))/self._xscale
+		self._velocity.y += (norm.y * (timedelta/100.0))/self._yscale
+
+	def _getMaxVelocity(self):
+		return self._maxvelocity
+		
+	def _setMaxVelocity(self, maxvel):
+		self._maxvelocity = maxvel/sqrt(self._xscale * self._yscale)
+
+	def _getLocation(self):
+		return self._instance.getLocation()
+		
+	def _setLocation(self, loc):
+		self._instance.setLocation(loc)
+
+	def _getInstance(self):
+		return self._instance
+	
+	def _setInstance(self, instance):
+		self._instance = instance
+	
+	def _getVelocity(self):
+		return self._velocity
+		
+	location = property(_getLocation,_setLocation)
+	instance = property(_getInstance, _setInstance)
+	velocity = property(_getVelocity)
+	maxvelocity = property(_getMaxVelocity, _setMaxVelocity)
\ No newline at end of file
--- a/demos/shooter/scripts/scene.py	Wed Mar 31 21:13:07 2010 +0000
+++ b/demos/shooter/scripts/scene.py	Thu Apr 01 17:03:34 2010 +0000
@@ -27,18 +27,73 @@
 from scripts.common.helpers import Rect
 
 
-
+class SceneNode(object):
+	def __init__(self, spaceobjects = None):
+		if not spaceobjects:
+			self._spaceobjects = list()
+		else:
+			self._spaceobjects = spaceobjects
+		
+	def _getObjects(self):
+		return self._spaceobjects
+		
+	def _setObjects(self, spaceobjects):
+		self._spaceobjects = spaceobjects
+		
+	spaceobjects = property(_getObjects, _setObjects)
 
 class Scene(object):
 	def __init__(self, engine, objectLayer):
 		self._engine = engine
 		self._model = engine.getModel()
 		self._layer = objectLayer
+		self._nodes = list()
 		
 		self._player = Player(self._model, 'player', self._layer)
 		self._projectiles = list()
 		self._lasttime = 0
 		
+		self._maxnodes = 128
+
+	def initScene(self, mapobj):
+		layer = mapobj.getLayer('objects')
+		xscale = layer.getCellGrid().getXScale()
+				
+		enemies = layer.getInstances('enemy')
+		
+		#initialize our scene array to some arbitrary size
+		for i in range(0,self._maxnodes):
+			self._nodes.append(SceneNode())
+		
+		for instance in enemies:
+			loc = instance.getLocation().getExactLayerCoordinates()
+			
+			objectName = instance.getObject().getId()
+			print objectName
+			
+			enemy = Ship(self._model, 'enemy', self._layer, False)
+			enemy.instance = instance
+			
+			nodeindex = int(loc.x * xscale)
+			self._nodes[nodeindex].spaceobjects.append(enemy)
+
+	def getObjectsInNode(self, node):
+		return self._nodes[node].instances
+
+	def getObjectsInRange(self, rangeL, rangeR):
+		objects = list()
+		
+		for i in range(rangeL, rangeR):
+			objects.extend(self._nodes[i].spaceobjects)
+			
+		return objects
+	
+	def checkCollision(self, instance1, instance2):
+		pos1 = instnace1.getLocation().getExactLayerCoordinates()
+		pos2 = instnace2.getLocation().getExactLayerCoordinates()
+		
+		
+	
 	def attachCamera(self, cam):
 		self._camera = cam
 		self._camera.setLocation(self._player.location)
@@ -56,6 +111,18 @@
 		exactloc.x += timedelta * 0.001
 		loc.setExactLayerCoordinates(exactloc)
 		self._camera.setLocation(loc)
+		
+		topleft = self._camera.toMapCoordinates(fife.ScreenPoint(0,0))
+		bottomright = self._camera.toMapCoordinates(fife.ScreenPoint(1024,768))
+
+		leftnode = int(topleft.x)
+		rightnode = int(bottomright.x) + 1
+		
+		if leftnode < 0:
+			leftnode = 0
+		if rightnode > self._maxnodes:
+			rightnode = self._maxnodes
+		collisionlist = self.getObjectsInRange(leftnode, rightnode)
 
 		self._player.update(timedelta, keystate, self._camera)
 		
--- a/demos/shooter/scripts/ships/player.py	Wed Mar 31 21:13:07 2010 +0000
+++ b/demos/shooter/scripts/ships/player.py	Thu Apr 01 17:03:34 2010 +0000
@@ -27,8 +27,8 @@
 
 
 class Player(Ship):
-	def __init__(self, scene, shipName, layer):
-		super(Player, self).__init__(scene, shipName, layer, True)
+	def __init__(self, model, playerName, layer):
+		super(Player, self).__init__(model, playerName, layer)
 		self._bounds = Rect(-100,-100,200,200)
 		
 	def update(self, timedelta, keystate, camera):
@@ -37,20 +37,20 @@
 		oldpos = self.location
 		
 		if keystate['UP']:
-			self.applyThrust(fife.DoublePoint(0,-0.075), timedelta)
+			self.applyThrust(fife.DoublePoint(0,-0.0075), timedelta)
 			key = True
 		if keystate['DOWN']:
-			self.applyThrust(fife.DoublePoint(0,0.075), timedelta)
+			self.applyThrust(fife.DoublePoint(0,0.0075), timedelta)
 			key = True
 		if keystate['LEFT']:
-			self.applyThrust(fife.DoublePoint(-0.075,0), timedelta)
+			self.applyThrust(fife.DoublePoint(-0.0075,0), timedelta)
 			key = True
 		if keystate['RIGHT']:
-			self.applyThrust(fife.DoublePoint(0.075,0), timedelta)
+			self.applyThrust(fife.DoublePoint(0.0075,0), timedelta)
 			key = True
 			
 		if not key and self._velocity.length() > 0:
-			self.applyBrake(0.075)
+			self.applyBrake(0.0075, timedelta)
 		
 		super(Player, self).update(timedelta)
 		
--- a/demos/shooter/scripts/ships/shipbase.py	Wed Mar 31 21:13:07 2010 +0000
+++ b/demos/shooter/scripts/ships/shipbase.py	Thu Apr 01 17:03:34 2010 +0000
@@ -24,46 +24,17 @@
 from math import sqrt
 
 from fife import fife
-from scripts.common.helpers import normalize
+from scripts.common.baseobject import SpaceObject
 from scripts.weapons import Weapon
 
-class Ship(object):
-	def __init__(self, scene, shipName, layer, uniqInMap=True):
-		self._scene = scene
-		self._name = shipName
-		self._layer = layer
-		self._xscale = self._layer.getCellGrid().getXScale()
-		self._yscale = self._layer.getCellGrid().getYScale()
 
-		if uniqInMap:
-			self._instance = self._layer.getInstance(self._name)
-		else:
-			#have to create instance here
-			self._instance = None
-		
-		#velocity as a vector
-		self._velocity = fife.DoublePoint(0,0)
+class Ship(SpaceObject):
+	def __init__(self, model, name, layer, findInstance=True):
+		super(Ship, self).__init__(model, name, layer, findInstance)
+
 		self._maxvelocity = 0.025/sqrt(self._xscale * self._yscale)
 		self._timedelta = 0
 		self._weapon = None
-
-	def _getMaxVelocity(self):
-		return self._maxvelocity
-		
-	def _setMaxVelocity(self, maxvel):
-		self._maxvelocity = maxvel/sqrt(self._xscale * self._yscale)
-
-	def _getLocation(self):
-		return self._instance.getLocation()
-		
-	def _setLocation(self, loc):
-		self._instance.setLocation(loc)
-
-	def _getInstance(self):
-		return self._instance
-	
-	def _getVelocity(self):
-		return self._velocity
 	
 	def _setWeapon(self, weapon):
 		self._weapon = weapon
@@ -71,71 +42,11 @@
 	def _getWeapon(self, weapon):
 		return self._weapon
 		
-	def applyThrust(self, vector, timedelta):
-		self._velocity.x += (vector.x * (timedelta/1000.0))/self._xscale
-		self._velocity.y += (vector.y * (timedelta/1000.0))/self._yscale
-		
-		if self._velocity.length() > self._maxvelocity:
-			norm = normalize(self._velocity)
-			self._velocity.x = norm.x * self._maxvelocity
-			self._velocity.y = norm.y * self._maxvelocity
-		
-	
-	def applyBrake(self, brakingForce):
-
-		if self._velocity.length() <= .001:
-			self._velocity.x = 0
-			self._velocity.y = 0			
-			return
-		
-		#first normalize to get a unit vector of the direction we are traveling
-		norm = normalize(self._velocity)
-		if norm.length() == 0:
-			self._velocity.x = 0
-			self._velocity.y = 0
-			return
-			
-		#negate to get opposite direction
-		norm.x = norm.x * -1
-		norm.y = norm.y * -1
-		
-		#apply braking deceleration  
-		norm.x *= brakingForce
-		norm.y *= brakingForce
-		
-		self._velocity.x += (norm.x * (self._timedelta/1000.0))/self._xscale
-		self._velocity.y += (norm.y * (self._timedelta/1000.0))/self._yscale
-		
 	def fire(self, curtime):
 		if self._weapon:
 			return self._weapon.fire(curtime)
 		
 		return None
 	
-	def start(self):
-		pass
-
-	def update(self, timedelta):
-		self._timedelta = timedelta
-		
-		shiploc = self.location
-		exactloc = shiploc.getExactLayerCoordinates()
-		
-		exactloc.x += self._velocity.x
-		exactloc.y += self._velocity.y
-				
-		shiploc.setExactLayerCoordinates(exactloc)
-		self.location = shiploc
-	
-	def stop(self):
-		pass
-		
-	def destroy(self):
-		pass
-		
-	location = property(_getLocation,_setLocation)
-	instance = property(_getInstance)
-	velocity = property(_getVelocity)
-	maxvelocity = property(_getMaxVelocity, _setMaxVelocity)
 	weapon = property(_getWeapon, _setWeapon)
 	
\ No newline at end of file
--- a/demos/shooter/scripts/weapons.py	Wed Mar 31 21:13:07 2010 +0000
+++ b/demos/shooter/scripts/weapons.py	Thu Apr 01 17:03:34 2010 +0000
@@ -22,22 +22,19 @@
 # ####################################################################
 
 from fife import fife
+from scripts.ships.shipbase import SpaceObject
 
-class Projectile(object):
+class Projectile(SpaceObject):
 	def __init__(self, model, projectileName, layer, timeToLive):
-		self._model = model
+		super(Projectile, self).__init__(model, projectileName, layer, False)
 		self._name = projectileName
 		self._layer = layer
-		self._instance = None
-		self._velocity = None
+
 		self._obj = self._model.getObject(self._name, "http://www.fifengine.de/xml/tutorial")
 		self._running = False	
 		self._ttl = timeToLive
 		self._starttime = 0
-		
-		self._xscale = self._layer.getCellGrid().getXScale()
-		self._yscale = self._layer.getCellGrid().getYScale()
-		
+	
 	def create(self, location):
 		self._instance = self._layer.createInstance(self._obj, location.getExactLayerCoordinates(), "bullet")
 		fife.InstanceVisual.create(self._instance)
@@ -58,12 +55,6 @@
 			self._layer.deleteInstance(self._instance)
 			self._running = False
 		
-	def _getLocation(self):
-		return self._instance.getLocation()
-		
-	def _setLocation(self, loc):
-		self._instance.setLocation(loc)
-		
 	def _isRunning(self):
 		return self._running
 	
@@ -83,7 +74,6 @@
 		else:
 			self.destroy()
 		
-	location = property(_getLocation,_setLocation)
 	running = property(_isRunning)
 	ttl = property(_getTTL)
 	
--- a/demos/shooter/scripts/world.py	Wed Mar 31 21:13:07 2010 +0000
+++ b/demos/shooter/scripts/world.py	Thu Apr 01 17:03:34 2010 +0000
@@ -88,6 +88,7 @@
 		
 		#give player the default weapon
 		self.scene.player.weapon = Weapon(self.model, self.map.getLayer('objects'), self.scene.player, 100)
+		self.scene.initScene(self.map)
 		
 	def initCameras(self):
 		"""