Complex animation made easy with ActionQueue
Ever needed to create a complex animation? Move 2 or more things at the same time?
One of the most powerful but unknown features of
ActionQueue is the ability to create your own animation functions that will do just that.
ActionQueue recognizes 2 types of actions: instant methods/functions, and time-based animation functions. For performance reasons normal function calls are executed without any frame updates inbetween. Time-based animations are something different as they (by definition) require frame updates to be visible. ActionQueue recognizes an animation if the passed method returns a
ActionQueuePerformData object.
How does that work? A queue can be created like this:
var queue:ActionQueue = new ActionQueue();
var duration:Number = 4.0;
queue.addAction( this, doAnimation, graphic_mc, duration, 0 0, 500, 400, Regular.easeOut );
queue.run();
The parameters passed to
addAction are just an example.
To let ActionQueue know an animation will be going on for 4 seconds, we will return an
ActionQueuePerformData object in
doAnimation:
public function doAnimation (inMC:MovieClip,
inDuration:Number,
inStartX:Number,
inStartY:Number,
inEndX:Number,
inEndY:Number,
inEffect:Function ) : ActionQueuePerformData {
var performFunction:Function = function (inPerc:Number) : Boolean {
// ...
}
var startValue:Number = 0;
var endValue:Number = 1;
return new ActionQueuePerformData( performFunction, inDuration, startValue, endValue, inEffect );
}
The function
performFunction will do all the work for us. It will get passed a percentage value between
startValue and
endValue.
Of course you can pass different parameters to
doAnimation. See
AQSpring? for an example of an example that does not use x, y, or duration.
Here is a complete example of our complex animation function:
public function doAnimation (inMC:MovieClip,
inDuration:Number,
inStartX:Number,
inStartY:Number,
inEndX:Number,
inEndY:Number,
inEffect:Function ) : ActionQueuePerformData {
// create a reference for performFunction
var ref:Controller = this;
// set up the animation function
var performFunction:Function = function (inPerc:Number) : Boolean {
// we will fade in the clip
ref.graphic_mc._alpha = ActionQueue.relativeValue( 0, 100, inPerc );
// ... animate the color from black to red
ColorUtils.setMixColor(ref.graphic_mc, 0x000000, 0xff0000, inPerc);
// ... make it grow to scale 500
ref.graphic_mc._xscale = ref.graphic_mc._yscale = ActionQueue.relativeValue( 100, 500, inPerc );
// ... move it across the stage
var x:Number = ActionQueue.relativeValue( inStartX, inEndX, inPerc );
x += 20 * Math.random() - 10; // move it erratically
ref.graphic_mc._x = x;
var y:Number = ActionQueue.relativeValue( inStartY, inEndY, inPerc );
y += 100 * Math.random() - 50; // move it erratically
ref.graphic_mc._y = y;
// meanwhile we will update the progress bar
ref.bar_mc._xscale = ActionQueue.relativeValue(0, 100, inPerc);
return true; // return false if we want to quit mid-air
};
// Set up the data so ActionQueue will perform the function performFunction:
var startValue:Number = 0;
var endValue:Number = 1;
return new ActionQueuePerformData( performFunction, inDuration, startValue, endValue, inEffect );
}
Note the use of
ActionQueue.relativeValue - this is a convenience method that calculates the value between start and end, given a percentage between 0 and 1. I use it quite a lot.
See it in action
Comments
BumBus - 08 Apr 2008:
Hi,
I m an noob in this, but I like do learn it. So why is the "Download Code" link broken.
Cheers Bum
ArthurClemens - 08 Apr 2008:
Thanks for pointing this out. I have updated the link.