Globally set your tweens man!

Vicious Worms

Lately I’ve been using the Tween class included in the flash ActionScript 3.0 for Flash CS3 library, and I noticed some peculiar behavior with respect to the motion of the Tweens. Often, especially when the program was undergoing points of extreme activity, my tweens would not complete their motions. It was perplexing, and my first attempt to fix the bug was to simply to listen for the tween to stop

(tween.addListener(TweenEvent.MOTION_FINISH,
                   fixPosition)

, and then to force the asset to its intended end point. This worked on a simple application: Selected Works Site, but it completely failed when I tried it on one with heavy processor activity.

So, after trawling the internet in search of others experiencing the same problem, I believe I found the solution in the comments at a blog called Everything Cool. (I aslo found they talked about it on the live docs). Here I’ll explain what the problem is, how to solve it, and at the same time show you how to use the fl.transitions.Tween class in Flash CS3.

A quick tutorial on the Tween Class.
First a few points.

  1. You always need to import the tween class when using tweens, even when coding on the timeline of an fla
  2. Tweens can be used on almost any kind of object, unlike the transition manager which forces your target to be a MovieClip
  3. The Flex framework has its own class of Tweens that work differently than the ones I’m describing here. You will need to search the web to figure out how to use these.

Ok, so I’m providing generalized code. The first 2 lines are the import statements, the 3rd is the variable declaration, and the remaining lines will be the actual tween itself, inside of a function that you can call anywhere. A tween automatically starts when it is called.

import fl.transitions.Tween;
import fl.transitions.easing.*;

var simpleMovement:Tween

private function startTween(e:MouseEvent):void{
   simpleMovement = new Tween(targetObject, "y",
 		      Strong.easeOut,
 		      targetObject.y,
 		      destinationValue,
 		      1, true);
}

You will see that the tween called “simpleMovement” takes 7 arguments. They are as follows (in order):

  1. Object to be tweened
  2. Value to be tweened. (Can be pretty much anything you desire… even filter values and sound volume)
  3. Easing method(you must import the easing class as supplied)
  4. Start value (supplied in this example as wherever the target object is currently located)
  5. End Value
  6. Length of tween in seconds. (a highly precise number… can use 0.3482)
  7. Use seconds… either true or false.

Now the problem I was having had to do with the scope of declaring my Tween object. Out of simple cohesion, or laziness I often put my tween declarations and the instantiations in the same function.

private function startTween(e:MouseEvent):void{
   var simpleMovement:Tween = new Tween(
                      targetObject, "y",
 		      Strong.easeOut,
 		      targetObject.y,
 		      destinationValue,
 		      1, true);
}

Well therein was my problem. In ActionScript 3.0, the garbage collector runs whenever there is a high number of discarded objects in the cue. (The garbage collector deletes objects with no reference) Because my tween was declared locally, and thus a weak reference, if the application went through an episode of high activity, it was highly likely that it would be discarded by the garbage collector before it could complete.

So eureka man, all I had to do was declare my Tween globally, and thus ensure the garbage collector wouldn’t mark it for deletion.

One Response to “Globally set your tweens man!”

  1. Alvin Says:

    Hi!! followed this link from my article, thanks for highlighting the crux of the issue. I hadnt investigated the issue in depth but I have since stuck to using Tweener for doing my Tweens, works a lot better for me.

    I had been deducing that it was the garbage collector but missed the part on the weak references.

    Alvin

Leave a Reply