Recipe 11.3. Easing


Problem

You want an object to smoothly move to a specific location, slow down, and stop as it reaches that spot.

Solution

Use an easing formula.

Discussion

First, we'll look at the concept of simple easing. You have an object at a certain position and you want it to ease to another position. Take the distance between the two points and move the object a fraction of that distancemaybe one-half, one-third, or less. On the next iteration, find the new distance and move the object a fraction of that. Continue this way until the object is so close to the target that you can consider it there.

You'll see that the first couple of jumps are quite big, but successive jumps get smaller and smaller until the object appears not to be moving at all. Viewed in terms of velocity, the velocity starts out high and approaches zero. Another way of looking at it is that velocity is dependent on distance. A large distance makes for a high velocity.

The following example shows a simple example of easing. The target position is specified by _targetX and _targetY. The fraction that the object moves each time is set in _easingSpeed. Here it is set to 0.1, which means the object moves one-tenth of the distance to the target on each animation interval:

package {     import flash.display.Sprite;     import flash.events.Event;     import flash.events.TimerEvent;     import flash.utils.Timer;          public class Easing extends Sprite {         private var _sprite:Sprite;         private var _easingSpeed:Number = 0.1;         private var _targetX:Number = 400;         private var _targetY:Number = 200;         private var _timer:Timer;                  public function Easing(  ) {             _sprite = new Sprite(  );             _sprite.graphics.beginFill(0x0000ff, 100);             _sprite.graphics.drawCircle(0, 0, 25);             _sprite.graphics.endFill(  );             _sprite.x = 50;             _sprite.y = 50;             addChild(_sprite);             _timer = new Timer(30);             _timer.addEventListener("timer", onTimer);             _timer.start(  );         }                  public function onTimer(event:TimerEvent):void {             var vx:Number = (_targetX - _sprite.x) * _easingSpeed;             var vy:Number = (_targetY - _sprite.y) * _easingSpeed;             _sprite.x += vx;             _sprite.y += vy;         }     }     }

One problem with this setup is that the timer continues to run, even after the object has gotten as close as it's going to get to the target. To handle that, find the distance to the target and if it is less than a certain value, just turn off the timer, as illustrated by the bolded code in the following example:

public function onTimer(event:TimerEvent):void {     var dx:Number = _targetX - _sprite.x;     var dy:Number = _targetY - _sprite.y;     var dist:Number = Math.sqrt(dx * dx + dy * dy);     if(dist < 1)     {         _sprite.x = _targetX;         _sprite.y = _targetY;         _timer.stop(  );     }     else     {         var vx:Number = dx * _easingSpeed;         var vy:Number = dy * _easingSpeed;         _sprite.x += vx;         _sprite.y += vy;     } }

This example first finds the distance on the two axes and the total distance. If the distance is less than 1, it places the object at the target point and kills the timer. Otherwise, it continues as normal.

Sometimes though, you may not want the easing to stop; for example, in a moving target. The following example has the object easing toward the mouse. In other words, it simply replaces mouseX and mouseY for _targetX and _targetY:

public function onTimer(event:TimerEvent):void {     var vx:Number = (mouseX - _sprite.x) * _easingSpeed;     var vy:Number = (mouseY - _sprite.y) * _easingSpeed;     _sprite.x += vx;     _sprite.y += vy; }

This is the simplest form of easing, and will suffice in a good many cases. Robert Penner (http://www.robertpenner.com), a well-known and highly respected Flash programmer, has developed a set of much more complex easing formulas that have become a sort of standard for easing applications. They even have been incorporated into the standard ActionScript classes that come with both Flash and Flex. At this writing, the equations are written for ActionScript 1.0 and 2.0 only, but they could easily be adapted for ActionScript 3.0. These equations do such things as easing in, easing out, easing in and out, or easing based on a specific time interval or number of frames, with many different formulas.

See Also

Recipes 11.1 and 11.2 for the basics on velocity.




ActionScript 3. 0 Cookbook
ActionScript 3.0 Cookbook: Solutions for Flash Platform and Flex Application Developers
ISBN: 0596526954
EAN: 2147483647
Year: 2007
Pages: 351

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net