Categories Displayed in Flash

Archive for the 'timeline' Category

Flash: Fast Prototyping and Sketching UI with FlowControl

While I enjoy the new power of Flash9/AS3.0, one of the things I really dislike about the AS3, is how much extra work to do basic things like setup buttons to do simple timeline control, this is especially hard on designers and animators who don't code. I agree with 5etdemi post 4 years ago, the basics have ironically gotten harder to do.

What wrong with ECMAScript/Actionscript? Well, it is not especially well suited for certain tasks, the worst of which is time-based/timeline-oriented animation and declarative drawing. I mean, it seems pretty ironic that ActionScript is derived from ECMAScript which was primarily oriented at scripting in a text-based environment, HTML and the DOM. Simply put, ActionScript has leaned more and more towards heavy lifting text operations (like RegEx and the new XML implementation) and less towards building programmatically what Flash was originally meant for, animation.

While there are useful utilities like Lee Brimelow's nice event generator utility, I wanted less, as even if being good with actionscript, when you have a few minutes to put together something for (or during!) a client/skype meeting, scripting isn't really an option. Thankfully AS3 has some tricks to help!

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.) ( press RIGHT arrow key to advance)

One tennant of Sketch is using the type and instance names to do most the event binding work, largely this is to allow Designers to stay on the timeline, but the same could apply to objects created in actionscript as well. So in the above example there are 2 scenes, and a bunch of empty frames, and a nav control. What's special is the buttons you see are actually just semi-transparent buttons (I call InvisiButtons) that have instance names like 'next', 'prev', (shown in the button names) there is no other script on the timeline for them. That via the FlowControl listening to ADDED event are autowired up to call 'nextFrame()' , 'prevFrame()' etc. These InvisiButtonscould be used as a hotspot over a comped image or basic text and wireframe graphics, allowing low to high fidelity comps to be created.

In this example a ENTER_FRAME event updates the TextField off to the right to show the current scene, frame et, to show where you are.
FlowControl has some other nifty features.

  • optional features is the fadein, fadeout effect, with configureable color, so while there is a normal timeline, the fade effect is free and ads a bit of polish IMHO.
  • tooltips telling you where the buttons go/do.
  • keypress for left/right arrow to go to the next previous frame, escape to goto first frame-useful for slide shows
  • XXX_autoBtn. If it sees this pattern that button will generate an XXX event (e.g. sayHi_autoBtn generates a new Event("sayHi"), which anybody is free to listen to.

All these are in the example (as well as all the code for FlowControl) on code.google.
Flow Control can be used 'embedded' as the document level class (or extending from it) or loaded as an external swf, and I'll be demoing that in the future. That latter feature is more targetted to creating highly skinnable games which I'll be covering in future blog posts.

AS3: How low can you go? Tny, a 1.9KB Tweening engine for Banner Ads

Challenged by a Banner ad size limit, I was curious how small I could create a tweening engine with basic color and sound support. Got it down to 1919 bytes, it can get down to ~1500 bytes if you don't need sound or color. Leaving room for more assets (damn Myriad Pro is a hog!)

Of course it's not just for banner ads, it basically wraps a given DisplayObject (including TextFields), and behaves just like setting properties of a clip directly (x, y, xscale), except that it eases to get there. Setting the duration acts as the play().

This makes it pretty easy to prototype with, so much so I'm contemplating using it as the proxy for whever I normally position things, to force me to think about motion earlier, just set duration = 0, and it will jump to the end.  It shares the same basic API as Tweeny, so progressive enhancement (if you need the playhead API) is easy to do.
It' s not the fastest engine purely on code, but with rendering overhead, it's among the best available in GreenSock's great little starfield tweening benchmark util

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Here's an example of tweening the color and position of textfields, note that the engine is 1.9K, this banner is 10K due to fonts:

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Using this code.

  1.  
  2. import com.troyworks.core.tweeny.*;
  3.  
  4. //similar to t1.target = txt1;
  5. var t1:Tny = new Tny(txt1);
  6. var t2:Tny = new Tny(txt2);
  7. var t3:Tny = new Tny(txt3);
  8. var t4:Tny = new Tny(txt4);
  9.  
  10. //Setup colors to cycle through
  11. var c:Array =[0xFFFFFF, 0xCCCCCC, 0x333333, 0x000000];
  12.  
  13. //Set Bounds //
  14. var ow = stage.width - txt.width - 100;
  15. var oh = stage.height - 80;
  16.  
  17. function jump(t:Tny):void {
  18.         t.x =  txt.width + (ow * Math.random());
  19.         t.y = (oh* Math.random());
  20.         t.scaleY = t.scaleX  = Math.random()*3;
  21.         t.ease = Elastic.easeInOut;
  22.         /////// Re-Cycle Colors ////////////
  23.         var cc = c.shift();
  24.         t.color = cc;
  25.         t.colorP =10; //10% tint
  26.         c.push(cc);
  27.  
  28.         t.delay = Math.random() * 1;
  29.         t.duration = Math.random() * 4  + .5;
  30.         ///// on complete callback self ////
  31.         t.onComplete = jump;
  32.         t.onCompleteParams =[t];
  33. }
  34.  
  35. jump(t1);
  36. jump(t2);
  37. jump(t3);
  38. jump(t4);

It's open source, it will be up after the first of the year, still trying to figure out how to get google code's SVN to show up on the blog, and there may be a bug or two lurking I haven't found yet.

As an aside, as this post hopefully shows, the blog is improving technically in periodic jumps, with some exciting upgrades planned in 2008. While a webdev pro, It's my first time professionally blogging and first time using Wordpress. Over the weekend upgraded to the latest, moved it to the correct domain, added several plugins for flash, code snippets sand spam filtering so comments and registration have been reenabled should work correctly. Permalink structures have changed so hopefully google will start indexing correctly by post instead of category.

In theory you should be able to subscribe to changes on pages you're interested in.

AS3: Prelude to Tweeny, a fast and flexible Tweening engine

So I've been working over the weekend on the Tweening engine based on Cogs affectionately called Tweeny. I find it highly amusing as I've been working in Flash since Flash 4, I have built so many presentation engines it borders on comical when every new client inevitably asks for a powerpoint lite clone, and consider myself relatively advanced,..yet how much of a loop this one threw me for.

WhileI had an AS2.0 class already working, it's taken me 3 days to get the basics working in AS3.0. This is because yesterday I totally got schooled on Matrixes with Senocular's most excellent tutorial, (my brain still hurts) and then excited by Penner's lurking MatrixTransform and ended up scrapping several paragraphs that comprise most the standard tween engines. I find myself building this next presentation engine in a way that bears no resemblence to most engines I've used or seen, partly due on the architecture difference between AS3.0 and prior, and partly expanding the role of Tweening beyond the simple display classes. Every time I added a new feature or solved a bug, I found a way to make things simpler.
Matrixes are cool, as you can get away with just easing the Begin and End matrixes rather than doing every calculation, plus you get the ability to offset the registration point and skew, features both very useful for the Authoring type interfaces and kids content I'm creating. More power and more speed to boot! In running performance tests, it's about 2x faster than setting DisplayObject.rotate, DisplayObject.width, scale etc as most tween engines do. Not that running those scripts are typically the limiting factor relative to the overhead in rendering, but still it's nice to know that the underlying code isn't a bottle neck.
Like most Tween engines, Tweeny supports a pluggable easing that affects multiple properties (x, y, width etc) with individual ranges (x[-5, 100], pan[-1,1]). But something my math-whiz girlfriend help me realize was that since duration is fixed, the easing equasion (often filled with expensive Math operations) can be calculated once as the 'normal' and then scaled to the others ranges, cheaply with simple * + . This should significantly reduce tweening calculation overhead,...and dammit I like smart particles flying at 60fps!

To further that I realized that the normalized calculation, is easy to broadcast, so that other listeners keep in synch, and can conceivably modularize or patchwork tweens. One of the things that I've wanted to try for awhlie was a way to balance out top-down easing approaches with bottom up physics routine. This usually involves Euler or Verlet accumulation and integration of forces, but most tweening engines are rather possessive when it comes to updating display objects...only one at a time else they start overwriting, where's the fun in that?
Some other features I like, Sound or SoundChannel volume and pan, colorTransform tweening (which I use a lot for configuration dynamically styled UI's) easier constructors for Bounce and Elastic's extra params which I use with kids games.

One thing that I'm not currently planning on supporting soon is a JSON or XML based interface. I find it poor programming practice to do

TweenEngine.create(target, duration, {x:1,y:2, ....})

in AS3.0 when you can do:

var t:Tweeny = new Tweeny();
t.initFrom(target,duration);
t.x = 1;
t.y = 2;

t.addEventListener(...)

t.startFromBeginning();

Because using fully typed classes allow for autocomplete to help fill out the values, offer stricter type checking and setting of defaults. When they are on a line by line they are easy to comment out to turn on and off. There isn't any overhead to parse XML or JSON into useable values. Since it's part of the Class definition it should also be significantly faster than dynamically allocated Object properties on the prototype.
Keeping a tween around, keeps memory and garbage collection from churning, especially for most applications where the tween is reused over and over again to put thing back and forth. I realize why many tween engines opt not to go this route as managing transitions on top of other transitions can get tricky. But know that I know about these issues I'm glad I spent the extra time. Since Tweeny uses the Playhead API, it supports stop, rewind, play, playbackward etc, it's not really different than keeping an mp3 or swf around.
So far it's about 10K, so 3x larger than say Tweenlite, but much of that is the inclusion of the framework/Cogs is useful for many other things, websites and games especially, and I'm still working on it.
The morning had an epiphany and I was able to tie together many of the related ideas into a cohesive model, so I have a roadmap for the next few months, and even a relatively simple Authoring UI for all the features exposed. Looking at the one pager of noteobook, probably 7 boxes, and only a few UI elements, in that largely what I'm working on is creating much of the same metaphors (e.g. timeline) of Flash inside of Flash...just like Web 2.0 is largely recreating the OS inside of the WebBrowser. And Virtualization is recreating the connectivity of electronics. One that note, if your looking for good book on self-referentiality check out Gödel, Escher, Bach .

AS3: recreating onLoad, MovieClip.addFrameScript part duex

Recreating onLoad with MovieClip.addFrameScript

AS2 had an onLoad event, called after the frame's children had been created, which is largely how custom components were able to manipulate the visual state for useful things like:

  • register listeners.
  • hiding and showing clips (especially when multiple clips are stacked on top of each other for different error messages)
  • jumping to a frame,
  • setting up modal dialogs/mouse opaque areas

In AS3 this doesn't work the same, and this bites you on the occassion you have an actionscript class is registered to a class via the linkageID, like that of the "Document class.
If you try it you get the warning:

Warning: 1090: Migration issue: The onLoad event handler is not triggered automatically by Flash Player at run time in ActionScript 3.0. You must first register this handler for the event using addEventListener ( 'load', callback_handler).

So you think, ok, easy enough. Just add an eventListener to load. Test movie and then nothing happens. Search the help docs, and you find zero references to 'load' event. Check DisplayObject and you find every other event (render, added, etc) than the one we are looking for. Leads to one of two possibilities. One the load event doesn't exist... or second the load event has already been called prior to the class constructor being called, so adding a reference to it won't actually do anything. I can't really tell, I've tried searching and running some tests, and can't get it to work... which leads me to the question, just how do I accomplish all those in items above?

Thankfully the fix is easy: addFrameScript in the constructor.

addFrameScript(0,onLoadHandler); //works!!!
// addEventListener("load", onLoadHandler); // doesn't work

While on the subject,  in order to access clips on the  timeline from the *.as they should be public variables like this:

  • public var my_btn:SimpleButton
  • public var my_playerControls:MovieClip

and your class should be dynamic e.g

dynamic public class MyView extends MovieClip

Keeping the scripts already on the timeline.

Since your replacing the script call when it hits frame0, whatever is on the timeline won't be called. Thankfully since MovieClip is a dynamic class, scripts on the timeline are appended to the prototype, thus available by this which refers to the prototype chain instead of the class inheritance (Flash is multiple inheritance!). This is useful when the timeline has some configuration data/setup on it, and this approach allows you to call it prior or after your onLoadHandler

public function MyMovieClipClass(){

super();
addFrameScript(0,onLoadHandler);
// addEventListener("load", onLoadHandler); //doesn't work
trace(" AAAA CONSTRUCTOR AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
}
function onLoadHandler():void{
trace("BBBBB onLoadHandler BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
trace("onLoadHandler " + currentFrame);

///pre frameactions

if(!this["frame1"]){
this["frame1"]();
}

//post frameactions

my_btn.addEventListener(.....

my_playerControls.gotoAndStop("buffering");

}

OUTPUTS

  • AAAA CONSTRUCTOR
  • BBBB onLoadHandler
  • CCCC frame1TimelineScripts

Introduction to ActiveFrame, Cogs, Chain, Score, Sketch, fXperience

Intro to StateMachines

The good news is if your in team development, you've been diagramming them for years, as flowcharts and bubble diagrams. Bubbles are states, arrows are transitions. This is one of the keys to their usefulness in teams. The diagrams can be understood and modified by anybody, and can represent anything from a users interaction with the whole application, a game's AI, or the graphical transitions in a button rollover. Any Animator who has done keyframes and tweens knows has been unwittingly using states and transitions, but what about developers?
Most any application developer is familiar with OOP, and many design patterns like the State Pattern. Some may have heard of the term finite state machine (FSM) with a possible vague understanding of what one is/does, most are probably not familiar with Hierarchical state machines (HSM), which are especially powerful, especially in experience driven, Flash
and AIR content working with asynchorous network requests, and large media upload/downloads, long timeline, all of which have complicated life cycles with asynchronous call/callback.

I started using them in projects after first learning about them in software from Jonathan Kaye. After using a few different versions in a few different projects, and developing my own, I have been on a quest to spread the word ever since. OOP and SM's foundational aspects. They are orthogonal and complimentary, OOP describes the nouns of the system StateMachines's the behavior over time. An example the cat is meowing, cat is the noun, meowing is the current state, and it will change over time.

Intro to Cogs
Cogs is the AS3 library of statemachines, and common patterns that people can extend/plugin similar to how people reuse design patterns, to avoid reinventing the wheel. Just as in Design patterns, there are fundamental patterns, from simple toggleable button, to synchronized media players.

It's named Cogs first after the tiny teeth that compose gears, that when meshing properly make up engines which power most the mechanical world, and secondly Cognition as the meshing of neurons make up the engines of intelligence. Cogs primary use is increasing the intelligence of components, games, game AI, and applications, by several approaches:

Cogs allows you to ask where you are, where you can go, and automate chains of execution between two states. Often event driven components are black box event generators, identical events broadcast at different times mean completely different things (like NetConnection) this is far from simple.

The FSM and HSM are based on Miro Samek's approach of using functions instead of classes to represent states, this very low level implementation has several advantages, one of the first is being less code to understand and write. It also enables behavioral inheritance, similar to. Cogs is different in several ways from Miro's inspiring work in his book. First all possible transitions are supported instead of just the common ones, and are validated by the unit tests..and the testing framework itself being an FSM and supporting Asynchronous testing easily.

Ongoing I'm working on API's for deep history, serialization/deserialization a graphical visualizer, among other things.

ActiveFrame

Cogs is part/foundation of a larger framework named ActiveFrame. Which strives reduce commmon architectural decays, largely by decoupling.

  • A message bus enabling event decoupling,
  • Java Spring 'Dependency Injection' for Implementor Interface decoupling,
  • plus a decoupling of the UI and controller..which can live in completely different swfs, similar to AS2.0's Object registerClass.

It's reasonably small for all these features, allowing it to be used for components, games, game AI or full blown applications.Sketch

is the visual extension of the Cogs, to deal with the View/UI world (e.g. movieclips/timelines, sprites), common layout, and UI/controller decoupling communication. While Sketch can be used whereever Flash can go, it's strong points are design and script heavy projects, in teams that have strong separations between design and scripting... they don't even have to be working on the same file.

Since it's based on Cogs, it's very easy to prototype and if flow diagrams (state diagrams) are used in the IA and Creative phases, it can act as a common language between design, IA, and engineering, as diagrams can easily be translated to code and back, and reworked easily. It supports what I call "introspectable UI's", in that the statemachine can act as the model, and summarize all the active states supported options to generate an appropriate "where can I go from here" UI.

Chain

is the workflow component, it's coordinates dependent parallel and sequential and nested tasks, with asynchrous call/callbacks, providing status along the way. Some uses for this are preloading assets, playlists, unit testing, easing and tweens, build out and tear down of UI's.
Score

is the the parallel timeline orchestration component, similar to a Orchestral score for coordinating multiple instances with a single virtual playhead. Useful for overlapping events. It's similar to an actionscript version of the Flash IDE timeline.
fXperience

is the visual components library. This is based off Cogs/Sketch, components have a wider lifecycle than those built into Flash and Flex., e.g. a button transitioning in, transitioning to up, transitioning to over etc. They support easy and iteratible skinning, so projects can start out simply as a graphic than graduate to more complicated ones as need requires.

Misc

All are a part of the TroyWorks AS3 code library that is MIT licensed on google (but isn't finished/uploaded yet, API isn't stable) There are many other useful utilities, datastructures and components of interest I'll be covering in more detail as they get more fully flushed out and converted to AS3 from AS2, I'm trying to make sure I don't add something already in AS3, and take full advantage of AS3's architecture.