Gilles Vandenoostende

Hi, I'm Gilles Vandenoostende - designer, illustrator and digital busybody with a love of language, based in Ghent, Belgium.

AnimationSlicer

Hey all, long time no post. I’ve been very busy, what with my trip to Las Vegas for MIX08 (I still have to write a debrief for that), then a trip to San Francisco (still have to clean up and put my photos online), and a lot of hard work back at Proximity BBDO. But I’ve got some time now, so I decided to share something cool with you guys.

Any Flashdeveloper worth his salt knows the benifits (and shortcomings) of the cacheAsBitmap property. This property, introduced in Flash Player 8 3 years ago, enables the flash player to store a complex vector shape in its memory as a single rendered bitmapData object. The benifit of this, is rather than having to re-calculate/redraw every vector point manually every single frame, flash now only has to juggle 2 values, namely the x and y properties, of the cached object, resulting in massive performance gains in some cases.

cacheAsBitmap has a few downsides though, most noteably, the fact that as soon as you begin to scale or rotate your movieclip/sprite all performance gains are gone, but this is an acceptable sacrifice for most cases where cacheAsBitmap would be used, i.e. instances where there are lots of things moving on screen. More annoying though, is the fact that you can’t cache animated movieclips.

The reason I’m telling you all this, is because I recently had to create a crowdsurfing game for Proximity BBDO. You can see the result at http://www.wipbinnenmetkbc.be/ (just click the “Speel & Win” bubble to start the game). An obvious design challenge I faced was the fact that I had to get dozens of fully animated characters on screen at playable framerates. The solution for this though, was found in the first version of my special AnimationSlicer package.

The implementation couldn’t be simpler; You create a new animationslicer object, you assign it a movieclip containing timeline based animations (sorry, no support for scripted animations at this time), and it’ll automatically cache every single frame in the animation as a bitmapData object. Then, once it’s finished caching the entire movieclip, it simply replaces the movieclip on the stage and uses an internal timer to play the cached frames at a specified framerate, which can differ from the stage’s framerate – i.e. the game runs at 30fps, but all animations can run at 24fps, again gaining performance. Here’s some sample code:

import com.vandenoostende.animation.slicer.AnimationSlicer;

/**
*
*@param movieclip The movieclip containing the animation to be cached.
*@param framerate The framerate the animation should run at. If 0, it runs at the stage’s framerate
*@param id The id for the animation. The animationSlicer then stores the cached frames in a
* central repository under this id and re-uses the frames for future animations
* cached under the same id. If empty, it just creates a new set of cached frames
* every time. OPTIONAL
*/

function sliceAnimation(movieclip:MovieClip, framerate:int = 0, id:String = “”):AnimationSlicer{
return new AnimationSlicer(movieclip, true, true, framerate, id);
}

//slice the movieclip
sliceAnimation(animation_mc, 30, “animation_mc”);

This has a lot of advantages, the biggest of all being speed. Compare these 2 examples to see the immediate benifit from using my class
(be aware, it is possible that your computer might hang for a few moments when opening the ‘With’ link, as the site caches the animations first time round, I solved this in the game by writing a special preloader for the game which precached all required animations before starting the game proper) :

  1. With AnimationSlicer
  2. Without AnimationSlicer

(the animations are made by Eugene and Louise, freelance animators/designers from Antwerp, Belgium)As you can see, in some cases, this results in a nearly 500% increase in performance (5 fps vs. 24 fps). Of course, there are a couple of drawbacks:

1. Memory usage. As the slicer stores every single frame as an uncompressed bitmapdata object, this can get your memory usage quite out of hand if you’re not careful. I did forsee the ability to re-use cached frames between the same movieclips, so once animation has been cached you can re-use it across the entire site with zero memory increase and zero lag.
2. Initial caching phase. The first time you create an AnimationSlicer for a movieclip it runs through the animation step by step at 24 frames per second, regardless of the stage’s framerate. This was a concious design decision on my part, and serves to relieve the strain on the CPU during the caching phase. The animationslicer does dispatch a few events to let you know when the animation has finished caching. That way you can do a silent/invisible pre-cache without the user being exposed to jerky animations.
3. No scripted animation. As mentioned above, no scripting is supported at the moment. The animationSlicer does have most properties and methods a MovieClip does (i.e. gotoAndStop(), gotoAndPlay(), nextFrame(), and currentFrame, currentFrameLabel properties, as well as dispatching an ENTER_FRAME event, so you could easily write a wrapper class for the AnimationSlicer which turns the cached animation into something more controllable. I created several scripted animationloops for the game using this technique.
4. Same limitations as cachAsBitmap. So no scaling or rotating the animation after it’s been cached, or else you might get aliased pixels (jaggies).

If you can live with these shortcomings (some of which might be fixed in future releases, especially point 2 or 3), then you can reap the benifits of cached animations!

Click here to download. (sources and examples)


Creative Commons License

This work, unless otherwise expressly stated, is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 2.0 Belgium License

3 Comments

This is great Gilles! I will give it a try today, I wrote a class that converts anything intro a BitmapDataObject (reuses bitmapData across instances) so it saves memory, will post it soon.

Posted by Og2t at April 30th, 2009 at 1:44 am.

Hi Gilles,

I don’t suppose you have this class for AS2?

Thanks

Posted by Ben at May 14th, 2009 at 3:43 pm.

Sorry, no I don’t. The principle should be easy enough to port though, since it doesn’t use any real AS3 specific API’s, however I can’t vouch for the same increased performance as you’d get with the AS3 version.

Posted by admin at May 20th, 2009 at 3:03 am.

Back to top