Controlling actions using intervals

The gameplay of many great video games is defined by certain movement patterns as well as their speed and timing. For example, each of the ghosts in Pac-Man has its own and unique way of hunting the player. Another great sample for gameplay-defining movement patterns can be found in Half-Life, where a Headcrab, the simplest type of enemy, tries to attack directly from the front, while fighting Marines is harder as they are taking cover and try to flank the player.

Without the proper tools, defining such action sequences can be a very time-consuming and tedious task that often requires an experienced animator or games designer to make them seem natural and compelling. But with Panda3D and its intervals system, this won't be a problem for you after reading and working through the following recipe.

Getting ready

The following code and steps build on top of Setting up the game structure found in the Chapter 1, Setting Up Panda3D and Configuring Development Tools. Please complete this recipe before you proceed!

How to do it...

Complete these steps to get a running sample of Panda3D's intervals:

  1. Add the highlighted lines to the file Application.py:
    from direct.showbase.ShowBase import ShowBase
    from direct.showbase.RandomNumGen import RandomNumGen
    from direct.actor.Actor import Actor
    from panda3d.core import Vec3
    from direct.interval.IntervalGlobal import *
    class Application(ShowBase):
    def __init__(self):
    ShowBase.__init__(self)
    self.panda = Actor("panda", {"walk": "panda-walk"})
    self.panda.reparentTo(render)
    self.panda.setHpr(-90, 0, 0)
    self.panda.loop("walk")
    self.walkIval1 = self.panda.posInterval(2, Vec3(-8, 0, 0), startPos = Vec3(8, 0, 0))
    self.walkIval2 = self.panda.posInterval(2, Vec3(8, 0, 0), startPos = Vec3(-8, 0, 0))
    self.turnIval1 = self.panda.hprInterval(0.5, Vec3(90, 0, 0), startHpr = Vec3(-90, 0, 0))
    self.turnIval2 = self.panda.hprInterval(0.5, Vec3(-90, 0, 0), startHpr = Vec3(90, 0, 0))
    self.colorIval = Func(self.randomColor)
    self.pandaWalk = Sequence(self.walkIval1, self.turnIval1, self.colorIval, self.walkIval2, self.turnIval2, self.colorIval)
    self.pandaWalk.loop()
    self.cam.setPos(0, -50, 6)
    def randomColor(self):
    rand = RandomNumGen(globalClock.getFrameTime())
    self.panda.setColorScale(rand.random(), rand.random(), rand.random(), 255)
    
  2. Start the program by hitting F6. If your code is correct, you will see a panda walk from one side of the window to the other and back, changing its color every time it turns:
How to do it...

How it works...

Right after loading and adding the panda actor to the scene, we define four intervals that make the panda walk from one side to the other. The first two are position intervals that move an object from one point to the other, and the other two intervals are interpolating between two rotation values, all of which are getting passed similar parameters: The first value is the time we want the action to take until it is completed, followed by the final and starting positions.

Then we add a function interval. We cannot pass a time value to this kind of interval because it executes immediately. All the constructor of Func takes is the method to execute upon activation. Here we use the randomColor() method, which changes the panda's color tint to a random value.

Finally, all these intervals are put into a Sequence object. We use this to ensure that the intervals we defined before are executed in the order passed to the constructor of Sequence. We are creating a chain of actions. Our Sequence makes the panda walk from one side to the other, turn around, change its color, walk back to where it started, turn around again, and finally change its color yet another time. We start the sequence as a loop, set the camera, and the panda is on its way!

There's more...

Panda3D's interval system is very powerful and important and therefore deserves some more discussion, in order to give you a better understanding of its reach and power.

Lerp intervals

In the sample code above, we used shortcuts to directly create intervals for the panda actor. These shortcuts create instances of LerpPosInterval and LerpHprInterval, respectively. We can create instances of these classes directly, but we must not forget to pass the model or actor NodePath we want to modify as the first parameter of the constructor! There are even more very commonly used interpolation interval types: LerpQuatInterval lets us move objects from one rotation to another one using quaternions. LerpScaleInterval interpolates between two scale factors of a scene object. LerpColorInterval and LerpColorScaleInterval can be used to crossfade object colors. While the first one overrides the target object's initial color, LerpColorScaleInterval multiplies colors and tints models and actors in the given colors.

Also there are interval types that modify two or more object properties at the same time: LerpPosHprInterval, for example, interpolates the position and rotation at the same time, while LerpHprScaleInterval is used to rotate and scale. To top it off, a LerpPosHprScaleInterval does all of the aforementioned in parallel.

Lerp function interval

You can use a LerpFunc to continuously call a function or method over a given period of time, allowing you to, for example, change a parameter slightly with each iteration. The following code snippet shows how to use an interpolation function interval:

def someFunc(t):
print t
fn = LerpFunc(someFunc, fromData=0, toData=1, duration=10)
fn.start()

This brief snippet creates a LerpFunc that calls someFunc() over the course of ten seconds while passing values ranging from zero to one, which then will be printed to the console.

Interpolation easing

Passing in the blendType parameter to the constructor when creating a new LerpFunc can be used to modify the starting and stopping behaviors of interpolation intervals to be more smooth: 'noBlend', which is the default value, causes the interval to make a hard start and stop. Setting the blendType parameter to 'easeIn' makes the animation accelerate until it reaches its full speed. Passing 'easeOut' has the effect of making the interpolation decelerate smoothly before coming to a stop. If you intend to create a smooth animation without any sudden starting or stopping, set the blendType parameter to 'easeInOut'.

Sequences and Parallels

This recipe already has shown how to use the Sequence class to chain intervals, but sometimes you really want to coordinate actions so that they happen at the same time. This is what you can use objects of the type Parallel for—creation works analogous to Sequence, but all intervals you added will play in parallel once this interval has started.

Note

Sequences and Parallels can be nested within each other. Use this fact for creating very complex action patterns with great ease!

Wait interval

Panda3D features a special kind of interval called Wait. The only thing it does is to wait for the specified amount of time you pass to its constructor. Note that the Wait class is designed to be used in conjunction with a Sequence or Parallel.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset