Roll your own AS3 animation tools.


photo Ralph Unden

What is GoASAP?

It’s a versatile, generic base library for building animation tools in ActionScript 3.0.

A tweening kit?

Totally not. Go isn’t a kit that tries to do it all, but in a geeky way is actually much more exciting: it enables any AS3 coder to build a rock-solid animation library of your own design! So instead of being stuck with one kit’s set of limitations, you’ll be able to constantly expand your own set of tools for each project – keeping you engaged and inventive. Go is made for creative coders and R-&-D-ready teams.

 

Other systems out there are top-down and exclusive; GoASAP is roots-up and inclusive. The many systems built on Go are cross-compatible too, which is a big deal because it means that systems can be combined, modded, hybridized... with no performance loss. Tools as diverse as John Grden's strict-typed Go3D and Donovan Adams' HydroTween, which has a tweener-like syntax but supports sequencing. (see sidebar)

What’s in it?

Some concrete building-block classes & interfaces; a few key architectural concepts; and a very fast pulse engine.

 

GoEngine

It starts with GoEngine, the only class required to use the Go platform. GoEngine is like a sophisticated timer class designed to run animations as efficiently as possible.

It’s been proven that animation runs fastest when items are grouped into a list. GoEngine expands on this by allowing for multiple lists, so that you can run several different pulses within one program (like a fast pulse for the main animations of a game, and a slower pulse for the readouts around the game’s chrome, for an overall speed improvement) – but still keep things centralized and fast.

 

Objects don’t have to be very special to be used with GoEngine, they just need to implement IUpdatable which simply declares one update() method and a pulseInterval property. So the possibilities are wide open for animation items.

‘Playable’ Building Blocks

IPlayable: Almost any animation system you build needs play controls. Go provides a generic interface: start(), stop(), pause(), resume() and skipTo(). Rewind and fast-forward are left out since they don’t necessarily apply to physics animation, and since you can do those things using skipTo. What Go does not do is tell you where you have to use these controls; it just provides them.

 

PlayableBase: If you’re building animation tools from scratch, you usually accompany this interface with the class PlayableBase, which provides a state property and the play-state constants STOPPED, PAUSED, PLAYING_DELAY, and PLAYING.

 

GoEvent: All animation API’s are time-based and so they end up having very similar event types. Go recognizes this and so it provides the most common and universal ‘playable’ event types: START, STOP, UPDATE, PAUSE, RESUME, CYCLE and COMPLETE.

 

This killer class/interface/event combo sets up a standard set of expectations, so that any utility that is ‘playable’ has a single clear set of play controls, play-states, and event types. For example you can pause() a tween, a parallel group or a sequence the same way, listen for a PAUSE event, and check whether its state is PAUSED. (Examples: see these elements in action in the tween, parallel and sequence classes provided with GoASAP.)

Tween, Parallel & Sequence

The stuff I’ve described above is what could be considered a ‘core compatibility layer’, meaning that if many diverse animation systems use the same building blocks they will all be easier to use together, hybridize, blend, and modify.

 

But Go also ships with some handy-dandy utilities that do the lion’s share of hard work in building a tweening API. (We also plan to include base classes for physics, so get involved if that's your thing!)

 

And yes, I said Sequence – Go ships with working parallel & sequence utilities called PlayableGroup, Sequence, and SequenceCA. (CA means “custom advance,” it lets you define any criteria on which to step a sequence forward.) So the very minute you get your first tween class working, you can immediately group it, chain it, and loop it.

 

LinearGo is the robust tween base class provided by Go.

 

It can be used on its own like this:

var startX:Number = sprite1.x;
var changeX:Number = 200;
function doAnimation(event:GoEvent):void {
    sprite1.x = startX + changeX * (event.target as LinearGo).position;
}
// params are delay, duration, easing var t:LinearGo = new LinearGo(.5, 2, Exponential.easeOut); t.addEventListener(GoEvent.UPDATE, doAnimation); t.start();

But to package a tween for reuse it’s best to extend LinearGo. You can learn how to “roll your own” in the video Build a Tween over Go in 3 Easy Steps. LinearGo provides all standard functionality you would expect from a tween, but the fabulous part is that it doesn’t define any specific targets or properties – or their data-types – so you get to design your own system based on your likes and dislikes.

 

Like, if you use Flex or FDT and love straight OO code hinting goodness, you might write a few tweens that works like this, shown here with Go's Sequence utility:

var s:Sequence = new Sequence();
s.addStep( new ScaleTween(box, 2, 2) );
s.addStep( new PositionTween(box, 100, 200) );
s.addStep( new PropTween(box, "rotation", 180, .5, 2), true );
s.addStep( new FadeOut(box) );
s.addEventListener(GoEvent.COMPLETE, onSequenceDone);
s.start();

Or maybe you prefer a syntax like this:

var t:ObjTweenMG = new ObjTweenMG(targ, {x:200,
                                         rotation:180,

                                         scaleX:5,
                                         delay:0,

                                         duration:2,

                                         ease:Back.easeInOut});

Or this:

var t:MultiTweenMG = new MultiTweenMG(targ,
                                      ["x","rotation","scaleX"],        
                                      [200, 180, 5],
                                      0,
                                      2,
                                      Back.easeInOut);
t.start();

Once you have a tween or two, you can write a parser. It's crazy easy.

(See the video: Build a Fuse-like Tween & Sequence Parser in Minutes.)

QuickParser.sequence({ target: targ1,
                       x:50,
                       scaleX:1.5,
                       duration:.5,
                       easing:Quadratic.easeIn
                     },
                     { target: targ1,
                       y:-10,
                       scaleY:1.5,
                       duration:.5,
                       useRelative:true,
                       easing:Quadratic.easeOut
                     },
                     { target: targ1,
                       rotation:360,
                       alpha:0
                     });

That is of course, just one syntax style – you might prefer an XML parser instead:

var x:XMLAnimator = new XMLAnimator();
x.addTarget(sprite1);
x.addStep(<tween ease="Quintic.easeInOut">
            <x useRelative="true">100</x>
          </tween>);
x.start();

None of these samples represent Go's syntax though, because in Go there is no syntax. These are just hypothetical examples of how you can put your own classes together in your own way.

Is that it – just an engine, base classes and utils?

Almost, yes! Go is very simple.

 

But ask yourself: what if you generate two tween objects that both handle scaleX on sprite1 at once? What if those were created in different parts of a program that weren’t aware of each other? You might expect an animation kit to prevent such things from happening – the first item to be killed off as the conflicting one is started.

 

In Go, if you want to prevent conflicts between items you call this setup command once:

 

GoItem.addManager(new OverlapMonitor());

 

But if you don’t need that management between items and don’t want it slowing your program down, you don’t have to use it – it’s entirely optional.

 

Advanced coders will be interested in this specific architectural side of Go that addresses cross-item management:

Not only is it entirely extensible – you can you write any custom manager you want (say, a hit-test checker for example) – but users get the final say in picking which managers they compile and activate for their project.

 

Management in Go is broken down into a couple of very simple interfaces, IManager and IManageable. This means that absolutely zero management is ‘baked into’ Go’s codebase, but when you need a smarter system, you can make custom managers for any purpose. Imagine a custom game engine, where part of the logic that runs the game is actually linked very directly into your core animation system. This is an entirely different scenario than cobbling together a bunch of bulky API’s to try and get a job done – it instead hints at tight integration between your animation tools and your programs. Yet it stays ‘loosely coupled’ since managers are optional.

 

There is no fat to trim; Go allows you to build simple animation units like tweens all the way through complex self-managing and tightly integrated systems, but you only compile and use just what’s needed for any given project.

How much time to get rolling with GoASAP?


If you’ve read this page, you should already have a pretty clear idea of what Go is for, what it contains, and why you might want to give it a try. You should now be able to watch the first video and be building your first successful LinearGo extension in about half an hour. You can immediately start sequencing your tweens with the Sequence class, and grouping them with the PlayableGroup class.

 

Building animation tools is not for everyone. You might want to just get familiar with the Go system then use tools shared around the community.

 

Don't be intimidated though; Go is easy enough for any OO coder to understand. Invest an hour or so into learning a little more, take a few baby steps by building a few tweens, and you’ll probably get a power rush pretty fast when you realize that you now have the ability to design and create your very own animation library. Later you can open-source license & share your cool tools at the GoPlayground.

 

If you work for a company, your team now has a 3rd option to going fully DIY or using prefab kits: you can invest a bit of time in a system that will reward you for branching out with every new challenge. In theory, Go should help you stay more engaged and inventive, because it lets you participate in doing real animation R & D, instead of production work. Try asking your boss: Would you prefer to have a team of production artists, or invest a few hours into R & D and get a team that's able to build, publish & publicize its own animation library?