CodeSnippets Simple Actor

From PyWiki

Jump to: navigation, search

Newbies: Simple Actor

This is a very simple re-usable actor class, designed to be extended.

# A Very Basic game actor class and simple example implementation.
 
class BasicActor:
 
    # simple initial setup
    # Override appropriate options for your character
    def __init__(self):
        self.speed = 5.0
        self.decisionTime = 5.0 + random.randint(2, 10)
        self.direction = ogre.Vector2(random.uniform(-1.0, 1.0), random.uniform(-1.0, 1.0))
        self.scale = ogre.Vector3(0.1,0.1,0.1)
        self.name = "Actor"
        self.mesh = "Cube.mesh"
        self.animating = False
        self.animation = None
 
    # 'spawn' is called by the game to create the character at a certain position
    # the scenemanager and actor count are passed in as well.
    def spawn(self, sceneManager, position, numActors):
        self.timer = 0.0
        self.ent = sceneManager.createEntity(self.name + "_" + str(numActors), self.mesh)
        self.posNode = sceneManager.getRootSceneNode().createChildSceneNode()
        self.rotNode = self.posNode.createChildSceneNode()
        self.posNode.setScale(self.scale)
        self.rotNode.attachObject(self.ent)
        self.posNode.setPosition(position)
        self.alive = True
        self.postSpawn()
 
    # this is equivalent to 'Remove' or 'Destroy'. ogre reccomends not destroying
    # scene nodes during the game, so we de-activate instead. the actor can be
    # re-used if needed without recreating it. in the game you can easily keep a 
    # tracker of hidden actors and only create new ones when you need to.
    def hide(self):
        self.posNode.setVisible(False)
        self.alive = False
 
    def show(self):
        self.posNode.setVisible(True)
        self.alive = True
 
    # override to set any individual options. see the example
    def postSpawn(self):
        pass
 
    # called from the game mainloop
    def update(self, time):
        if self.alive:
            self.timer += time
            if self.timer >= self.decisionTime:
                self.timer = 0
                self.think(time)
            if self.animating:
                self.animate(time)
            if self.moving:
                self.move()
 
    # simple linear movement       
    def move(self):
        pos = self.posNode.position
        off = self.direction * (self.speed * time)
        self.posNode.setPosition(pos.x + off.x, pos.y, pos.z + off.z)
 
    # do any skeletal animation
    def animate(self, time):
        self.animation.addTime(time)
 
    # do any AI
    def think(self, time):
        pass
 
 
# Here's an example class showing a walking robot
 
class Robot(BasicActor):
    def __init__(self):
        BasicActor.__init__(self)
        self.name = "Roboto"
        self.mesh = "robot.mesh"
 
    def postSpawn(self):
        self.posNode.yaw(ogre.Degree(-90))
        self.animation = self.ent.getAnimationState('Walk')
        self.animation.Enabled = True
        self.moving = True
        self.animating = True
 
    def think(self, time):
        self.direction = ogre.Vector2(random.uniform(-1.0, 1.0), random.uniform(-1.0, 1.0))
        self.direction.normalise()
        self.posNode.setDirection(self.direction.x, 0, self.direction.y, self.posNode.TS_WORLD)

In your game, when creating the scene you could do this:

def _createScene(self):
 
        ...
 
        self.robots = []
        for i in range(10):
            robo = Robot()
            robo.spawn(self.sceneManager, ogre.Vector3(200 + (i * 10), 10, 50), i)
            self.robots.append(robo)

Then in a frameListener or your own render loop, or whenever you want really:

def updateGame(self, time):
 
        ...
 
        for r in self.robots:
            r.update(time)