- Panda3d 1.7 Game Developer's Cookbook
- Christoph Lang
- 1084字
- 2021-04-09 21:21:47
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:
- 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)
- 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 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 Lerp
ColorScaleInterval
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!
- Creo 4.0中文版從入門到精通
- 中文版Illustrator CC實(shí)用教程
- Inkscape 0.48 Illustrator's Cookbook
- AI繪畫:Stable Diffusion從入門到精通
- Photoshop CC 2017從入門到精通
- Flash Facebook Cookbook
- Linux Shell Scripting Cookbook
- 中文版AutoCAD 2022從入門到精通
- 魔法詞典:AI繪畫關(guān)鍵詞圖鑒(Midjourney版)
- Photoshop 2021中文版入門、精通與實(shí)戰(zhàn)
- VMware Virtual SAN實(shí)戰(zhàn)
- Jasmine JavaScript Testing
- Ruby on Rails Web Mashup Projects
- The 3CX IP PBX Tutorial
- AutoCAD 2020中文版完全自學(xué)一本通