bharling
06-09-2006 10:39:49
Fixed it myself 
was trying to be too clever for my boots, seems that I cant use a dictionary to store the list of possible Actor classes, so I've swapped the dictionary lookup in the datamanager for a standard 'if name=="robot": actor = robot()' -type setup. Now on with the game!
Hi, (Sorry about the length of this post...)
I've built myself a simple game framework, based on the sourcecode for 'Violent World' (thanks, authors of VW). I'm getting quite far quite quickly (the joys of writing in python), however I've hit a problem which I cant seem to solve.
Like in VW, all the game characters are individual classes, subclassed from a basic gameActor class, and spawned by calling the actor's 'Spawn' method. A datamanager exists which holds a dictionary containing tuples in the form of {'ActorName' : ActorClassInstance()}. When each actor spawns, the datamanager first looks up the class in the dictionary, then calls the actor's __init__() method, then attaches the nodes, and logs the characters animation state, movement speed and direction, just like in VW. Every frame, a framelistener tells the datamanager to loop through its list of actors and update those that require updating. I've got 10 actors which all seem to spawn correctly (their models appear in-game, and their class instances contain all the needed properties and methods, but I can only get one of them to move, no matter what i do
. The robots have a simple ai, that tells them to periodically choose a new plant in the game and run towards it.
So if anyone can help, heres the bits of code which I think are causing the problem, but I dunno what it is....
GameActor Class:
RunningObject Class:
Robot Class:
Datamanager which spawns the 'bots
here is how I am spawning the 'bots from the main game
lastly, the framelistener does this every frame
So, thats it. If anyone has any ideas, I would appreciate some help! When I've tested this, the first robot spawns, but seems to run at double speed, and all the other robots seem to target the same plant (the last one in the list). As far as I can tell, the datamanager is calling 'move' on all the robots every time it updates, but they are stuck in place. I know all the actors are working (at least initally), because they all update their heights to rest on the landscape properly.
thanks for any replies

EDIT: PS. am using pyogre 1.0.6 on win32

was trying to be too clever for my boots, seems that I cant use a dictionary to store the list of possible Actor classes, so I've swapped the dictionary lookup in the datamanager for a standard 'if name=="robot": actor = robot()' -type setup. Now on with the game!
Hi, (Sorry about the length of this post...)
I've built myself a simple game framework, based on the sourcecode for 'Violent World' (thanks, authors of VW). I'm getting quite far quite quickly (the joys of writing in python), however I've hit a problem which I cant seem to solve.
Like in VW, all the game characters are individual classes, subclassed from a basic gameActor class, and spawned by calling the actor's 'Spawn' method. A datamanager exists which holds a dictionary containing tuples in the form of {'ActorName' : ActorClassInstance()}. When each actor spawns, the datamanager first looks up the class in the dictionary, then calls the actor's __init__() method, then attaches the nodes, and logs the characters animation state, movement speed and direction, just like in VW. Every frame, a framelistener tells the datamanager to loop through its list of actors and update those that require updating. I've got 10 actors which all seem to spawn correctly (their models appear in-game, and their class instances contain all the needed properties and methods, but I can only get one of them to move, no matter what i do

So if anyone can help, heres the bits of code which I think are causing the problem, but I dunno what it is....
GameActor Class:
class GameActor:
def __init__(self):
self.life = 100
self.price = 0
self.id = -1
self.position = (100.0, 0.0, 0.0)
self.moving = False
self.heightAdjust = 0.0
self.adjustHeight = True
self.direction = (1.0, 0.0, 0.0) # X, Y, Z
self.targetDirection = self.normalize((1.0, 0.0, 0.0)) # X, Y, Z
self.defaultDirection = self.normalize((1.0, 0.0, 0.0)) # X, Y, Z
self.calculateTargetEachFrame = False
self.rotateCritical = False
self.rotationSpeed = 5.0
self.speed = 1.0
self.maxSpeed = 0.0
self.target = None
self.name = "actor"
self.mesh = "sphere.mesh"
self.material = "Examples/RustySteel"
self.raySceneQuery = None
self.ray = ogre.Ray()
self.Alive = False
self.IsAnimated = False
self.DyingAnimation = None
self.hasAI = False
def SetTarget(self, gameActor):
self.target = gameActor
self.calculateTargetDirection()
def Spawn(self, position, SceneManager, numActors, RaySceneQuery):
rootnode = SceneManager.rootSceneNode
self.raySceneQuery = RaySceneQuery
self.Entity = SceneManager.createEntity("ent_" + self.name + str(numActors),self.mesh)
self.OgreNode = rootnode.createChildSceneNode("ogrenode" + str(numActors))
self.Node = self.OgreNode.createChildSceneNode("node_" + self.name + str(numActors))
self.name = str(self.name) + str(numActors)
## self.Node.position = position
self.Node.attachObject(self.Entity)
self.position = position
self.OgreNode.position = ogre.Vector3(self.position)
self.Alive = True
self.updateHeight()
...
RunningObject Class:
class RunningObject(GameActor):
def __init__(self):
GameActor.__init__(self)
self.animationSpeed = 1.0
self.animationState = None
self.hasAI = True
def move(self, time):
delta = time * self.speed
self.position = ( self.position[X] + self.direction[X] * delta,
self.position[Y] + self.direction[Y] * delta,
self.position[Z] + self.direction[Z] * delta)
self.OgreNode.position = ogre.Vector3(self.position)
self.updateHeight()
Robot Class:
class Robot(RunningObject):
def __init__(self):
RunningObject.__init__(self)
self.mesh = "Robot.mesh"
self.IsAnimated = True
self.animationState = "Walk"
self.speed = 40.00
self.updateAITime = 3
self.updateAIFrequency = 7
# This is broken somehow
#
def Update(self, actorsList):
# just change target for now
potentialTargets = [t for t in actorsList.keys() if "Plant" in t]
x = random.randrange(2, 60)
self.target = actorsList[potentialTargets[x]]
self.SetTarget(self.target)
self.calculateTargetDirection()
Datamanager which spawns the 'bots
...
def GatherGameObjects(self):
"""Return a dictionary of all game objects, and their
corresponding classes"""
return {"PlantSml":foliage.PlantSml(), "PlantTall":foliage.PlantTall(),
"PoliceGrunt": pigs.PoliceGrunt(), "Robot": pigs.Robot()}
...
def SpawnChar(self, name, position):
# The first point at which any game actor is created
actor = self.GameObjects[name]
actor.__init__()
actor.Spawn(position, self.SceneManager, self.NumActors, self.raySceneQuery)
self.actorsList[actor.name] = actor
self.NumActors = self.NumActors + 1
if (actor.IsAnimated):
actor.animationState = actor.Entity.getAnimationState(actor.animationState)
self.animationStates.append(actor.animationState)
self.animationStates[-1].enabled = True
return actor.name
def GetActiveObjects(self):
self.animationStates = []
self.animationSpeeds = []
for actor in self.actorsList.values():
if actor.IsAnimated and actor.Alive:
self.animationStates.append(actor.animationState)
self.animationSpeeds.append(actor.animationSpeed)
self.animationStates[-1].enabled = True
return self.animationStates
def UpdateGame(self, time):
self.updateAITime += time
self.totalTime += time
mc = 0
for actor in self.actorsList.values():
if actor.Alive and actor.moving:
actor.move(time)
if actor.hasAI:
if abs((self.updateAITime % actor.updateAIFrequency) - actor.updateAITime) <= time/2:
actor.Update(self.actorsList)
if actor.dot(actor.direction, actor.targetDirection) < 0.995:
actor.rotate(time)
for index in xrange(0,len(self.animationStates)):
self.animationStates[index].addTime(time * self.animationSpeeds[index])
here is how I am spawning the 'bots from the main game
for i in range(10):
robot = self.datamanager.SpawnChar("Robot", ogre.Vector3(ogre.Math.RangeRandom(100, 500),200.0,500.0))
myrobot = self.datamanager.actorsList[robot]
tarName = "Plant" + str(i + 10)
myrobot.Update(self.datamanager.actorsList)
## myrobot.SetTarget(self.datamanager.actorsList[tarName])
myrobot.Node.yaw(ogre.Degree(90))
myrobot.moving = True
self.datamanager.GetActiveObjects()
lastly, the framelistener does this every frame
def frameStarted(self, frameEvent):
# update all animations
self.datamanager.UpdateGame(frameEvent.timeSinceLastFrame)
So, thats it. If anyone has any ideas, I would appreciate some help! When I've tested this, the first robot spawns, but seems to run at double speed, and all the other robots seem to target the same plant (the last one in the list). As far as I can tell, the datamanager is calling 'move' on all the robots every time it updates, but they are stuck in place. I know all the actors are working (at least initally), because they all update their heights to rest on the landscape properly.
thanks for any replies

EDIT: PS. am using pyogre 1.0.6 on win32