gTween: Programmatic Tweening for AS3 Developers

There are a lot of great tweening engines out there. Personally, I'm a huge fan of Jack Doyle's TweenLite (and he's been incredibly productive adding new features lately). However, none of these libraries exactly fit the needs of me and my team. I wanted an engine that was small, fast, hugely flexible, and built from the ground up for AS3 and developers.

The result was gTween. gTween is a small (4.5kb), fast (1500 instances, 0.5s duration, ~25fps), instance based tweening class, with a huge number of options and capabilities. You can read about core features of gTween below.

This is certainly not an attempt to displace any of the existing tween engines. Rather, it's simply an attempt to share another option for managing programmatic tweens with the developer community.

For now, I am releasing this as a public beta. It has been loosely tested, but there is so much capability in gTween that I guarantee there are still bugs and edge cases we haven't addressed. Likewise, I am soliciting input on additions or modifications to the API (including the names of specific properties or methods), so it is possible that the API may change in the future.

Quick Feature Overview

Developer Oriented Proxy Tweening Interruptible Sequencing Timing Modes Pause All Events Resource Management Etc

Developer Oriented (consistent AS3 experience)

gTween is built for ActionScript 3 developers from the ground up. It uses a more conventional instance-oriented model, rather than a static interface. It also leverages the AS3 event model instead of callbacks (see Events). This provides a familiar, consistent experience for AS3 developers to work with tweens.

Here's a simple example of setting up a tween, and listening for the complete event.

var myTween:GTween = new GTween(mySprite, 2, {x:200});
myTween.addEventListener(Event.COMPLETE, handleTweenComplete);

Instances can either be referenced or transient. The former allows for changing values and behaviour on the fly (see Sequencing), and the latter works with smart resource management logic to ensure the tween won't be collected until it is finished running (see Resource Management).

Examples of referenced versus transient instances:.

 // hold a reference in myTween, so we can modify it later
var myTween:GTween = new GTween(mySprite, 2, {x:200});
// run once, and then free tween for garbage collection
new GTween(mySprite1, 2, {x:400});

gTween will also work with any numeric property of any object. You can use it to tween the volume of a sound, the size of an AIR window, or the value of "foo" on a custom object type, as easily as you would tween the x property of a Sprite.

Proxy Tweening

gTween provides a unique proxy property that allows you to work with tween destination values the same way you would work with them on the target object. The proxy object effectively "stands in" for your target object.

This simple example shows how you can use the proxy to move the target object 100 pixels to the right.

myTween.proxy.x += 100;

In the above example, the proxy will retrieve the x value from the target object (if it doesn't already exist as a destination value in the tween), add 100, and set it back as a destination value for the tween.

This is a very powerful feature that takes a little getting used to. Take a look at the proxy listing in the full API documentation for more information and examples.

Interrupting Tweens (make changes on the fly)

With gTween, you can modify your tween while it is playing, and it will attempt to accommodate those changes.

The user closes a panel before its done sliding in? Just reverse() it, and it will slide back closed from its current position. Need to move a sprite to a different location, or add an alpha fade out while the tween is running? Just adjust the values on the fly.

Here's a simple example showing how you can tween a sprite to the location a user clicks on stage. Note that the user can click at any time, and the tween will adjust itself to smoothly reach the destination.

var myTween:GTween = new GTween(mySprite,1);
stage.addEventListener(MouseEvent.CLICK,handleClick);
function handleClick(evt:MouseEvent):void {
   myTween.proxy.x = mouseX;
   myTween.proxy.y = mouseY;
}

You can also jump to the end or beginning of a tween instantly with beginning() or end(). Calling end(true) will recursively end sequenced tweens.

Sequencing Tweens (child tweens, and nextTween)

gTween provides three features to allow for sequencing multiple tweens: child tweens, delay, and nextTween.

By using addChild, you can associate multiple tweens to act as children of your tween. These tweens will be synchronized with the parent tween when it runs. You can even choose to synchronize their durations so that they start and end at the same time.

You can also specify another tween to play when a tween ends using nextTween, and specify a delay period that a tween will wait before playing.

The following example demonstrates playing two tween synchronously, followed by a 2 second delay before a third tween plays.

var myTween1:GTween = new GTween(target1,3,{x:20});
var myTween2:GTween = new GTween(target2,0,{x:200});
myTween1.addChild(myTween2,true); // true = synch durations
var myTween3:GTween = new GTween(target3,3,{y:50});
myTween3.delay = 2;
myTween1.nextTween = myTween3;

Timing Modes (frame, time, or hybrid)

Another unique feature of gTween is support for multiple timing modes. You can use the common time based timing, frame based timing, or a hybrid timing model.

In the "time" timing mode, all durations and positions are specified in seconds, and updates are run at a configurable frequency (ex. every 50ms). This provides tight control over durations, but can use more CPU, and be a bit more choppy in high CPU scenarios.

Using the "frame" timing mode, all durations and positions are specified in frames, and updates are run each frame. This uses a bit less CPU, and allows you to synchronize your tween with timeline animations, but the overall time duration can be unpredictable in high CPU scenarios.

The "hybrid" mode updates each frame, but allows you to specify durations in seconds. Each frame the tween will adjust its position according to the elapsed time since the previous update.

GTween.timingMode = GTween.TIME;

Because it is unlikely developers will change modes during a project, it is specified as a class level property. However, gTween will continue to use the old setting with old tweens, which allows you to change the mode at any time.

Pause All

Being able to pause all tweens can be handy. Pause all of the sprites in your game when the user pauses it, or pause all the active transitions when you open a dialog.

gTween offers a class level pauseAll property that will pause all tweens, without affecting their per instance paused property. Handy!

myTween.paused = false;
GTween.pauseAll = true; // pause ALL tweens.
trace(myTween.paused); // false

Robust Events

gTween offers three built in events: an activate event that lets you know when a tween starts running, an init event that fires when the tween finishes delaying and starts tweening, a change event that fires each time the tween updates, and a complete event that fires when it reaches its end.

Not enough? gTween allows you to dynamically add custom progress points to your tween that will fire when the tween reaches that point.

The following example shows how you can receive an event when a 3 second tween passes the halfway point (1.5 seconds), and get back a "halfway" string:

var myTween:GTween = new GTween(target1, 3, {alpha:1});
myTween.addProgressPoint(1.5,"halfway");
myTween.addEventListener(GTween.PROGRESS,onProgress);
function onProgress(evt:Event):void {
   trace(String(myTween.lastProgressPoint));
}

Note that you can associate any type of data with a progress point. A string labelling the point, a function to call when you reach that point, another tween to run, anything you want.

Resource Management

Resource management is important. You don't want old tweens hanging around using CPU and memory. You also don't want unreferenced tweens being garbage collected while they are still active.

Besides being developed with the AVM2 garbage collector in mind, gTween also uses a couple of strategies to allow unreferenced tweens to be collected when they are no longer needed, while preventing them from being destroyed when they are needed.

  1. If a tween is targeted at an object that extends EventDispatcher (like Sprite), it will subscribe itself as a listener to that object for a dummy event while its active. This allows the tween to be collected when it ends, or as soon as its target becomes elligible for collection.
  2. If its target is not an EventDispatcher, the tween adds itself to a class level collection while it is active. This keeps it from being collected until it is finished running.

gTween has been tested creating 3000 new tween instances per second with no memory leaks.

Additional Features

gTween has a lot of additional features. I'm not going to write about all of them, but here are a few:

  • autoHide, sets the target's visible to false when the tweened alpha is 0
  • autoReverse, reverses the tween when it ends (and plays it backwards if autoPlay is true).
  • smartRotate, rotates in shortest direction
  • supports using setSize for tweening height and width on components
  • support for updating properties like matrix and colorTransform automatically during a tween.
  • jump to any point in a tween by setting position.
  • loop a tween by setting nextTween equal to the same tween.
  • determine the state of a tween with the state and paused properties.
  • roundValues makes a tween round all tweened values before setting them on the target.

Download

To access the API documentation, and download the latest build of GTween, visit the GTween page at gskinner.com/libraries/gtween/.

Please provide any feedback or bug reports in the comments below.

Updates:

Sep 3, 2008: Beta 2 has been released. Learn more about it by clicking here.

Nov 4, 2008: Beta 3 has been released. Learn more about it by clicking here.