by
Voetsjoeba | 9
December 2006
In the previous page,
we reviewed what we want our easing function to do in
three statements.
We can write those 3 statements inside the onEnterFrame
handler’s body as a single statement like this:
- var
speed:Number
= 2;
- ease
=
function(
what:MovieClip
, to:Number
){
- what.onEnterFrame
=
function(){
- this._x
=
to –
(
to –
this._x
)
/
speed;
- }
- }
And there we go ! We have achieved a function that will
easy any MovieClip to any point on the x axis, in just
these 6 lines of ActionScript ! Excellent, but we have
been ignoring something up till now: this onEnterFrame
handler has not been told to ever stop, which means it
will still be calculating even long after the
destination has been ‘reached’.
Theoretically, it can never reach its destination, much
like 0.9999999…. will never reach 1. But, computers have
limitations in calculating floating point numbers, and
therefore so does Flash, and so do screens. At a certain
point you’ll end up calculating these insanely small
numbers, and moving the MovieClip on the stage by that
distance won’t have any effect, because those amounts
won’t even add up to a hundredth of an actual pixel to
move.
So, we have to build in some kind of a check to see when
the MovieClip has very closely neared its destination,
and then remove the onEnterFrame handler. That way, the
onEnterFrame handler won’t keep calculating values that
have no effect anyway. This is important in big projects
where CPU load is an issue. Trust me, you do not want an
onEnterFrame stalling in the background for every
MovieClip you’ve ever eased around.
Therein lies a problem: because the MovieClip will never
actually reach its destination, it is pointless to check
if it has. What we could do is set some kind of ‘null
distance’ that will determine how far the MovieClip
needs to be away from its destination to be considered
‘there’. This method works well if you stick to a
certain speed and ease all MovieClips using that speed,
but unfortunately it does not make for a good general
solution. This is because the null distance depends on
the speed of the easing. The slower the speed, the
slower the object will be moving towards its
destination, and the finer the dividing of the
distances. The finer the dividing of the distances, the
more MovieClip positioning limitations will take effect.
This makes the null distance method fairly unreliable.
A better solution is to keep track of the previous
positions of the MovieClip, and compare them to
each other. There will always be a certain point where
the difference between the distances will be so small
that Flash won’t bother to update the MovieClip to that
position because moving a MovieClip over such a small
distance is either meaningless or simply impossible.
When that happens, two consequent positions will be the
same, indicating that Flash has reached its limitation
of MovieClip positioning and that further calculations
will have no effect anymore. This is when we want our
loop to end.
Fortunately, performing this check is easy. All we need
is an extra variable that holds the previous position.
When we move the MovieClip to its new position, we check
if this new position is the same as the last one. If it
is, then we have reached our limit and we can safely
kill the loop because further calculations are pointless
as they will all result in the same position. And to
ensure maximum positioning accuracy, we can set our
MovieClip to its exact destination once this happens.
Just to be sure.
With that in mind, we can redefine our easing function
like this:
- var
speed:Number
= 2;
- ease
=
function(
what:MovieClip
, to:Number
){
- var
previousPosition:Number
=
what._x;
- what.onEnterFrame
=
function(){
- this._x
=
to –
(
to –
this._x
)
/
speed;
- if(
this._x
==
previousPosition
){
- this._x
=
to;
- delete
this.onEnterFrame;
- }
- previousPosition
=
this._x;
- }
- }
Onwards to the next page!
|