fb1eb6026b
git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@212 ed5b42cb-e716-0410-a449-f6a68f950b19
125 lines
3.3 KiB
ActionScript
125 lines
3.3 KiB
ActionScript
package com.threerings.flash {
|
|
|
|
import flash.display.DisplayObject;
|
|
import flash.display.Sprite;
|
|
|
|
import flash.events.Event;
|
|
|
|
import flash.utils.getTimer; // func import
|
|
|
|
/**
|
|
* Manages animations.
|
|
*/
|
|
public class AnimationManager
|
|
{
|
|
public function AnimationManager ()
|
|
{
|
|
throw new Error("Static only");
|
|
}
|
|
|
|
/**
|
|
* Start (or restart) the specified animation.
|
|
*/
|
|
public static function start (anim :Animation) :void
|
|
{
|
|
var dex :int = _anims.indexOf(anim);
|
|
if (dex == -1) {
|
|
dex = _anims.length;
|
|
_anims.push(anim);
|
|
}
|
|
_anims[dex + 1] = getTimer(); // mark it as starting
|
|
|
|
// and update it immediately
|
|
anim.updateAnimation(0);
|
|
|
|
if (!_framer) {
|
|
_framer = new Sprite();
|
|
_framer.addEventListener(Event.ENTER_FRAME, frameHandler);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stop the specified animation.
|
|
*/
|
|
public static function stop (anim :Animation) :void
|
|
{
|
|
var dex :int = _anims.indexOf(anim);
|
|
if (dex == -1) {
|
|
Log.getLog(AnimationManager).warning("Stopping unknown Animation: " + anim);
|
|
return;
|
|
}
|
|
|
|
// remove it
|
|
_anims.splice(dex, 2);
|
|
|
|
// See if we should clean up a bit
|
|
if (_anims.length == 0) {
|
|
_framer.removeEventListener(Event.ENTER_FRAME, frameHandler);
|
|
_framer = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Track a DisplayObject that is also an Animation- it will
|
|
* automatically be started when added to the stage and
|
|
* stopped when removed.
|
|
*/
|
|
public static function addDisplayAnimation (disp :DisplayObject) :void
|
|
{
|
|
if (!(disp is Animation)) {
|
|
throw new ArgumentError("Must be an Animation");
|
|
}
|
|
|
|
disp.addEventListener(Event.ADDED_TO_STAGE, startDisplayAnim);
|
|
disp.addEventListener(Event.REMOVED_FROM_STAGE, stopDisplayAnim);
|
|
if (disp.stage != null) {
|
|
// it's on the stage now!
|
|
start(Animation(disp));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stop tracking the specified DisplayObject animation.
|
|
*/
|
|
public static function removeDisplayAnimation (disp :DisplayObject) :void
|
|
{
|
|
disp.removeEventListener(Event.ADDED_TO_STAGE, startDisplayAnim);
|
|
disp.removeEventListener(Event.REMOVED_FROM_STAGE, stopDisplayAnim);
|
|
if (disp.stage != null) {
|
|
stop(Animation(disp));
|
|
}
|
|
}
|
|
|
|
protected static function startDisplayAnim (event :Event) :void
|
|
{
|
|
start(event.currentTarget as Animation);
|
|
}
|
|
|
|
protected static function stopDisplayAnim (event :Event) :void
|
|
{
|
|
stop(event.currentTarget as Animation);
|
|
}
|
|
|
|
/**
|
|
* Handle the ENTER_FRAME event.
|
|
*/
|
|
protected static function frameHandler (event :Event) :void
|
|
{
|
|
var now :Number = getTimer();
|
|
var anim :Animation;
|
|
var startStamp :Number;
|
|
for (var ii :int = _anims.length - 2; ii >= 0; ii -= 2) {
|
|
Animation(_anims[ii]).updateAnimation(now - Number(_anims[ii + 1]));
|
|
}
|
|
}
|
|
|
|
/** The current timestamp, accessable to all animations. */
|
|
protected static var _now :Number;
|
|
|
|
/** All the currently running animations. */
|
|
protected static var _anims :Array = [];
|
|
|
|
protected static var _framer :Sprite;
|
|
}
|
|
}
|