Mercurial > fife-parpg
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): """