mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2026-04-01 14:31:34 +03:00
Update mobile version to mobile v2.2.1
The android version just got a much needed update to fix some resolution issues on devices with cutouts. It turns out the mobile source was actually pretty out of date, like 3 versions out of date! This commit brings it up to date. All the changes have just been about keeping the game running on modern devices, though. The biggest change was adding the Starling library to the project, which made the game GPU powered and sped the whole thing up.
This commit is contained in:
140
mobile_version/src/starling/animation/DelayedCall.as
Normal file
140
mobile_version/src/starling/animation/DelayedCall.as
Normal file
@@ -0,0 +1,140 @@
|
||||
// =================================================================================================
|
||||
//
|
||||
// Starling Framework
|
||||
// Copyright Gamua GmbH. All Rights Reserved.
|
||||
//
|
||||
// This program is free software. You can redistribute and/or modify it
|
||||
// in accordance with the terms of the accompanying license agreement.
|
||||
//
|
||||
// =================================================================================================
|
||||
|
||||
package starling.animation
|
||||
{
|
||||
import starling.core.starling_internal;
|
||||
import starling.events.Event;
|
||||
import starling.events.EventDispatcher;
|
||||
|
||||
/** A DelayedCall allows you to execute a method after a certain time has passed. Since it
|
||||
* implements the IAnimatable interface, it can be added to a juggler. In most cases, you
|
||||
* do not have to use this class directly; the juggler class contains a method to delay
|
||||
* calls directly.
|
||||
*
|
||||
* <p>DelayedCall dispatches an Event of type 'Event.REMOVE_FROM_JUGGLER' when it is finished,
|
||||
* so that the juggler automatically removes it when its no longer needed.</p>
|
||||
*
|
||||
* @see Juggler
|
||||
*/
|
||||
public class DelayedCall extends EventDispatcher implements IAnimatable
|
||||
{
|
||||
private var _currentTime:Number;
|
||||
private var _totalTime:Number;
|
||||
private var _callback:Function;
|
||||
private var _args:Array;
|
||||
private var _repeatCount:int;
|
||||
|
||||
/** Creates a delayed call. */
|
||||
public function DelayedCall(callback:Function, delay:Number, args:Array=null)
|
||||
{
|
||||
reset(callback, delay, args);
|
||||
}
|
||||
|
||||
/** Resets the delayed call to its default values, which is useful for pooling. */
|
||||
public function reset(callback:Function, delay:Number, args:Array=null):DelayedCall
|
||||
{
|
||||
_currentTime = 0;
|
||||
_totalTime = Math.max(delay, 0.0001);
|
||||
_callback = callback;
|
||||
_args = args;
|
||||
_repeatCount = 1;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public function advanceTime(time:Number):void
|
||||
{
|
||||
var previousTime:Number = _currentTime;
|
||||
_currentTime += time;
|
||||
|
||||
if (_currentTime > _totalTime)
|
||||
_currentTime = _totalTime;
|
||||
|
||||
if (previousTime < _totalTime && _currentTime >= _totalTime)
|
||||
{
|
||||
if (_repeatCount == 0 || _repeatCount > 1)
|
||||
{
|
||||
_callback.apply(null, _args);
|
||||
|
||||
if (_repeatCount > 0) _repeatCount -= 1;
|
||||
_currentTime = 0;
|
||||
advanceTime((previousTime + time) - _totalTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
// save call & args: they might be changed through an event listener
|
||||
var call:Function = _callback;
|
||||
var args:Array = _args;
|
||||
|
||||
// in the callback, people might want to call "reset" and re-add it to the
|
||||
// juggler; so this event has to be dispatched *before* executing 'call'.
|
||||
dispatchEventWith(Event.REMOVE_FROM_JUGGLER);
|
||||
call.apply(null, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Advances the delayed call so that it is executed right away. If 'repeatCount' is
|
||||
* anything else than '1', this method will complete only the current iteration. */
|
||||
public function complete():void
|
||||
{
|
||||
var restTime:Number = _totalTime - _currentTime;
|
||||
if (restTime > 0) advanceTime(restTime);
|
||||
}
|
||||
|
||||
/** Indicates if enough time has passed, and the call has already been executed. */
|
||||
public function get isComplete():Boolean
|
||||
{
|
||||
return _repeatCount == 1 && _currentTime >= _totalTime;
|
||||
}
|
||||
|
||||
/** The time for which calls will be delayed (in seconds). */
|
||||
public function get totalTime():Number { return _totalTime; }
|
||||
|
||||
/** The time that has already passed (in seconds). */
|
||||
public function get currentTime():Number { return _currentTime; }
|
||||
|
||||
/** The number of times the call will be repeated.
|
||||
* Set to '0' to repeat indefinitely. @default 1 */
|
||||
public function get repeatCount():int { return _repeatCount; }
|
||||
public function set repeatCount(value:int):void { _repeatCount = value; }
|
||||
|
||||
/** The callback that will be executed when the time is up. */
|
||||
public function get callback():Function { return _callback; }
|
||||
|
||||
/** The arguments that the callback will be executed with.
|
||||
* Beware: not a copy, but the actual object! */
|
||||
public function get arguments():Array { return _args; }
|
||||
|
||||
// delayed call pooling
|
||||
|
||||
private static var sPool:Vector.<DelayedCall> = new <DelayedCall>[];
|
||||
|
||||
/** @private */
|
||||
starling_internal static function fromPool(call:Function, delay:Number,
|
||||
args:Array=null):DelayedCall
|
||||
{
|
||||
if (sPool.length) return sPool.pop().reset(call, delay, args);
|
||||
else return new DelayedCall(call, delay, args);
|
||||
}
|
||||
|
||||
/** @private */
|
||||
starling_internal static function toPool(delayedCall:DelayedCall):void
|
||||
{
|
||||
// reset any object-references, to make sure we don't prevent any garbage collection
|
||||
delayedCall._callback = null;
|
||||
delayedCall._args = null;
|
||||
delayedCall.removeEventListeners();
|
||||
sPool.push(delayedCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
mobile_version/src/starling/animation/IAnimatable.as
Normal file
30
mobile_version/src/starling/animation/IAnimatable.as
Normal file
@@ -0,0 +1,30 @@
|
||||
// =================================================================================================
|
||||
//
|
||||
// Starling Framework
|
||||
// Copyright Gamua GmbH. All Rights Reserved.
|
||||
//
|
||||
// This program is free software. You can redistribute and/or modify it
|
||||
// in accordance with the terms of the accompanying license agreement.
|
||||
//
|
||||
// =================================================================================================
|
||||
|
||||
package starling.animation
|
||||
{
|
||||
/** The IAnimatable interface describes objects that are animated depending on the passed time.
|
||||
* Any object that implements this interface can be added to a juggler.
|
||||
*
|
||||
* <p>When an object should no longer be animated, it has to be removed from the juggler.
|
||||
* To do this, you can manually remove it via the method <code>juggler.remove(object)</code>,
|
||||
* or the object can request to be removed by dispatching a Starling event with the type
|
||||
* <code>Event.REMOVE_FROM_JUGGLER</code>. The "Tween" class is an example of a class that
|
||||
* dispatches such an event; you don't have to remove tweens manually from the juggler.</p>
|
||||
*
|
||||
* @see Juggler
|
||||
* @see Tween
|
||||
*/
|
||||
public interface IAnimatable
|
||||
{
|
||||
/** Advance the time by a number of seconds. @param time in seconds. */
|
||||
function advanceTime(time:Number):void;
|
||||
}
|
||||
}
|
||||
396
mobile_version/src/starling/animation/Juggler.as
Normal file
396
mobile_version/src/starling/animation/Juggler.as
Normal file
@@ -0,0 +1,396 @@
|
||||
// =================================================================================================
|
||||
//
|
||||
// Starling Framework
|
||||
// Copyright Gamua GmbH. All Rights Reserved.
|
||||
//
|
||||
// This program is free software. You can redistribute and/or modify it
|
||||
// in accordance with the terms of the accompanying license agreement.
|
||||
//
|
||||
// =================================================================================================
|
||||
|
||||
package starling.animation
|
||||
{
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
import starling.core.starling_internal;
|
||||
import starling.events.Event;
|
||||
import starling.events.EventDispatcher;
|
||||
|
||||
/** The Juggler takes objects that implement IAnimatable (like Tweens) and executes them.
|
||||
*
|
||||
* <p>A juggler is a simple object. It does no more than saving a list of objects implementing
|
||||
* "IAnimatable" and advancing their time if it is told to do so (by calling its own
|
||||
* "advanceTime"-method). When an animation is completed, it throws it away.</p>
|
||||
*
|
||||
* <p>There is a default juggler available at the Starling class:</p>
|
||||
*
|
||||
* <pre>
|
||||
* var juggler:Juggler = Starling.juggler;
|
||||
* </pre>
|
||||
*
|
||||
* <p>You can create juggler objects yourself, just as well. That way, you can group
|
||||
* your game into logical components that handle their animations independently. All you have
|
||||
* to do is call the "advanceTime" method on your custom juggler once per frame.</p>
|
||||
*
|
||||
* <p>Another handy feature of the juggler is the "delayCall"-method. Use it to
|
||||
* execute a function at a later time. Different to conventional approaches, the method
|
||||
* will only be called when the juggler is advanced, giving you perfect control over the
|
||||
* call.</p>
|
||||
*
|
||||
* <pre>
|
||||
* juggler.delayCall(object.removeFromParent, 1.0);
|
||||
* juggler.delayCall(object.addChild, 2.0, theChild);
|
||||
* juggler.delayCall(function():void { rotation += 0.1; }, 3.0);
|
||||
* </pre>
|
||||
*
|
||||
* @see Tween
|
||||
* @see DelayedCall
|
||||
*/
|
||||
public class Juggler implements IAnimatable
|
||||
{
|
||||
private var _objects:Vector.<IAnimatable>;
|
||||
private var _objectIDs:Dictionary;
|
||||
private var _elapsedTime:Number;
|
||||
private var _timeScale:Number;
|
||||
|
||||
private static var sCurrentObjectID:uint;
|
||||
|
||||
/** Create an empty juggler. */
|
||||
public function Juggler()
|
||||
{
|
||||
_elapsedTime = 0;
|
||||
_timeScale = 1.0;
|
||||
_objects = new <IAnimatable>[];
|
||||
_objectIDs = new Dictionary(true);
|
||||
}
|
||||
|
||||
/** Adds an object to the juggler.
|
||||
*
|
||||
* @return Unique numeric identifier for the animation. This identifier may be used
|
||||
* to remove the object via <code>removeByID()</code>.
|
||||
*/
|
||||
public function add(object:IAnimatable):uint
|
||||
{
|
||||
return addWithID(object, getNextID());
|
||||
}
|
||||
|
||||
private function addWithID(object:IAnimatable, objectID:uint):uint
|
||||
{
|
||||
if (object && !(object in _objectIDs))
|
||||
{
|
||||
var dispatcher:EventDispatcher = object as EventDispatcher;
|
||||
if (dispatcher) dispatcher.addEventListener(Event.REMOVE_FROM_JUGGLER, onRemove);
|
||||
|
||||
_objects[_objects.length] = object;
|
||||
_objectIDs[object] = objectID;
|
||||
|
||||
return objectID;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/** Determines if an object has been added to the juggler. */
|
||||
public function contains(object:IAnimatable):Boolean
|
||||
{
|
||||
return object in _objectIDs;
|
||||
}
|
||||
|
||||
/** Removes an object from the juggler.
|
||||
*
|
||||
* @return The (now meaningless) unique numeric identifier for the animation, or zero
|
||||
* if the object was not found.
|
||||
*/
|
||||
public function remove(object:IAnimatable):uint
|
||||
{
|
||||
var objectID:uint = 0;
|
||||
|
||||
if (object && object in _objectIDs)
|
||||
{
|
||||
var dispatcher:EventDispatcher = object as EventDispatcher;
|
||||
if (dispatcher) dispatcher.removeEventListener(Event.REMOVE_FROM_JUGGLER, onRemove);
|
||||
|
||||
var index:int = _objects.indexOf(object);
|
||||
_objects[index] = null;
|
||||
|
||||
objectID = _objectIDs[object];
|
||||
delete _objectIDs[object];
|
||||
}
|
||||
|
||||
return objectID;
|
||||
}
|
||||
|
||||
/** Removes an object from the juggler, identified by the unique numeric identifier you
|
||||
* received when adding it.
|
||||
*
|
||||
* <p>It's not uncommon that an animatable object is added to a juggler repeatedly,
|
||||
* e.g. when using an object-pool. Thus, when using the <code>remove</code> method,
|
||||
* you might accidentally remove an object that has changed its context. By using
|
||||
* <code>removeByID</code> instead, you can be sure to avoid that, since the objectID
|
||||
* will always be unique.</p>
|
||||
*
|
||||
* @return if successful, the passed objectID; if the object was not found, zero.
|
||||
*/
|
||||
public function removeByID(objectID:uint):uint
|
||||
{
|
||||
for (var i:int=_objects.length-1; i>=0; --i)
|
||||
{
|
||||
var object:IAnimatable = _objects[i];
|
||||
|
||||
if (_objectIDs[object] == objectID)
|
||||
{
|
||||
remove(object);
|
||||
return objectID;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Removes all tweens with a certain target. */
|
||||
public function removeTweens(target:Object):void
|
||||
{
|
||||
if (target == null) return;
|
||||
|
||||
for (var i:int=_objects.length-1; i>=0; --i)
|
||||
{
|
||||
var tween:Tween = _objects[i] as Tween;
|
||||
if (tween && tween.target == target)
|
||||
{
|
||||
tween.removeEventListener(Event.REMOVE_FROM_JUGGLER, onRemove);
|
||||
_objects[i] = null;
|
||||
delete _objectIDs[tween];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes all delayed and repeated calls with a certain callback. */
|
||||
public function removeDelayedCalls(callback:Function):void
|
||||
{
|
||||
if (callback == null) return;
|
||||
|
||||
for (var i:int=_objects.length-1; i>=0; --i)
|
||||
{
|
||||
var delayedCall:DelayedCall = _objects[i] as DelayedCall;
|
||||
if (delayedCall && delayedCall.callback == callback)
|
||||
{
|
||||
delayedCall.removeEventListener(Event.REMOVE_FROM_JUGGLER, onRemove);
|
||||
_objects[i] = null;
|
||||
delete _objectIDs[tween];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Figures out if the juggler contains one or more tweens with a certain target. */
|
||||
public function containsTweens(target:Object):Boolean
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
for (var i:int=_objects.length-1; i>=0; --i)
|
||||
{
|
||||
var tween:Tween = _objects[i] as Tween;
|
||||
if (tween && tween.target == target) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Figures out if the juggler contains one or more delayed calls with a certain callback. */
|
||||
public function containsDelayedCalls(callback:Function):Boolean
|
||||
{
|
||||
if (callback != null)
|
||||
{
|
||||
for (var i:int=_objects.length-1; i>=0; --i)
|
||||
{
|
||||
var delayedCall:DelayedCall = _objects[i] as DelayedCall;
|
||||
if (delayedCall && delayedCall.callback == callback) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Removes all objects at once. */
|
||||
public function purge():void
|
||||
{
|
||||
// the object vector is not purged right away, because if this method is called
|
||||
// from an 'advanceTime' call, this would make the loop crash. Instead, the
|
||||
// vector is filled with 'null' values. They will be cleaned up on the next call
|
||||
// to 'advanceTime'.
|
||||
|
||||
for (var i:int=_objects.length-1; i>=0; --i)
|
||||
{
|
||||
var object:IAnimatable = _objects[i];
|
||||
var dispatcher:EventDispatcher = object as EventDispatcher;
|
||||
if (dispatcher) dispatcher.removeEventListener(Event.REMOVE_FROM_JUGGLER, onRemove);
|
||||
_objects[i] = null;
|
||||
delete _objectIDs[object];
|
||||
}
|
||||
}
|
||||
|
||||
/** Delays the execution of a function until <code>delay</code> seconds have passed.
|
||||
* This method provides a convenient alternative for creating and adding a DelayedCall
|
||||
* manually.
|
||||
*
|
||||
* @return Unique numeric identifier for the delayed call. This identifier may be used
|
||||
* to remove the object via <code>removeByID()</code>.
|
||||
*/
|
||||
public function delayCall(call:Function, delay:Number, ...args):uint
|
||||
{
|
||||
if (call == null) throw new ArgumentError("call must not be null");
|
||||
|
||||
var delayedCall:DelayedCall = DelayedCall.starling_internal::fromPool(call, delay, args);
|
||||
delayedCall.addEventListener(Event.REMOVE_FROM_JUGGLER, onPooledDelayedCallComplete);
|
||||
return add(delayedCall);
|
||||
}
|
||||
|
||||
/** Runs a function at a specified interval (in seconds). A 'repeatCount' of zero
|
||||
* means that it runs indefinitely.
|
||||
*
|
||||
* @return Unique numeric identifier for the delayed call. This identifier may be used
|
||||
* to remove the object via <code>removeByID()</code>.
|
||||
*/
|
||||
public function repeatCall(call:Function, interval:Number, repeatCount:int=0, ...args):uint
|
||||
{
|
||||
if (call == null) throw new ArgumentError("call must not be null");
|
||||
|
||||
var delayedCall:DelayedCall = DelayedCall.starling_internal::fromPool(call, interval, args);
|
||||
delayedCall.repeatCount = repeatCount;
|
||||
delayedCall.addEventListener(Event.REMOVE_FROM_JUGGLER, onPooledDelayedCallComplete);
|
||||
return add(delayedCall);
|
||||
}
|
||||
|
||||
private function onPooledDelayedCallComplete(event:Event):void
|
||||
{
|
||||
DelayedCall.starling_internal::toPool(event.target as DelayedCall);
|
||||
}
|
||||
|
||||
/** Utilizes a tween to animate the target object over <code>time</code> seconds. Internally,
|
||||
* this method uses a tween instance (taken from an object pool) that is added to the
|
||||
* juggler right away. This method provides a convenient alternative for creating
|
||||
* and adding a tween manually.
|
||||
*
|
||||
* <p>Fill 'properties' with key-value pairs that describe both the
|
||||
* tween and the animation target. Here is an example:</p>
|
||||
*
|
||||
* <pre>
|
||||
* juggler.tween(object, 2.0, {
|
||||
* transition: Transitions.EASE_IN_OUT,
|
||||
* delay: 20, // -> tween.delay = 20
|
||||
* x: 50 // -> tween.animate("x", 50)
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* <p>To cancel the tween, call 'Juggler.removeTweens' with the same target, or pass
|
||||
* the returned 'IAnimatable' instance to 'Juggler.remove()'. Do not use the returned
|
||||
* IAnimatable otherwise; it is taken from a pool and will be reused.</p>
|
||||
*
|
||||
* <p>Note that some property types may be animated in a special way:</p>
|
||||
* <ul>
|
||||
* <li>If the property contains the string <code>color</code> or <code>Color</code>,
|
||||
* it will be treated as an unsigned integer with a color value
|
||||
* (e.g. <code>0xff0000</code> for red). Each color channel will be animated
|
||||
* individually.</li>
|
||||
* <li>The same happens if you append the string <code>#rgb</code> to the name.</li>
|
||||
* <li>If you append <code>#rad</code>, the property is treated as an angle in radians,
|
||||
* making sure it always uses the shortest possible arc for the rotation.</li>
|
||||
* <li>The string <code>#deg</code> does the same for angles in degrees.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public function tween(target:Object, time:Number, properties:Object):uint
|
||||
{
|
||||
if (target == null) throw new ArgumentError("target must not be null");
|
||||
|
||||
var tween:Tween = Tween.starling_internal::fromPool(target, time);
|
||||
|
||||
for (var property:String in properties)
|
||||
{
|
||||
var value:Object = properties[property];
|
||||
|
||||
if (tween.hasOwnProperty(property))
|
||||
tween[property] = value;
|
||||
else if (target.hasOwnProperty(Tween.getPropertyName(property)))
|
||||
tween.animate(property, value as Number);
|
||||
else
|
||||
throw new ArgumentError("Invalid property: " + property);
|
||||
}
|
||||
|
||||
tween.addEventListener(Event.REMOVE_FROM_JUGGLER, onPooledTweenComplete);
|
||||
return add(tween);
|
||||
}
|
||||
|
||||
private function onPooledTweenComplete(event:Event):void
|
||||
{
|
||||
Tween.starling_internal::toPool(event.target as Tween);
|
||||
}
|
||||
|
||||
/** Advances all objects by a certain time (in seconds). */
|
||||
public function advanceTime(time:Number):void
|
||||
{
|
||||
var numObjects:int = _objects.length;
|
||||
var currentIndex:int = 0;
|
||||
var i:int;
|
||||
|
||||
time *= _timeScale;
|
||||
if (numObjects == 0 || time == 0) return;
|
||||
_elapsedTime += time;
|
||||
|
||||
// there is a high probability that the "advanceTime" function modifies the list
|
||||
// of animatables. we must not process new objects right now (they will be processed
|
||||
// in the next frame), and we need to clean up any empty slots in the list.
|
||||
|
||||
for (i=0; i<numObjects; ++i)
|
||||
{
|
||||
var object:IAnimatable = _objects[i];
|
||||
if (object)
|
||||
{
|
||||
// shift objects into empty slots along the way
|
||||
if (currentIndex != i)
|
||||
{
|
||||
_objects[currentIndex] = object;
|
||||
_objects[i] = null;
|
||||
}
|
||||
|
||||
object.advanceTime(time);
|
||||
++currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentIndex != i)
|
||||
{
|
||||
numObjects = _objects.length; // count might have changed!
|
||||
|
||||
while (i < numObjects)
|
||||
_objects[int(currentIndex++)] = _objects[int(i++)];
|
||||
|
||||
_objects.length = currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private function onRemove(event:Event):void
|
||||
{
|
||||
var objectID:uint = remove(event.target as IAnimatable);
|
||||
|
||||
if (objectID)
|
||||
{
|
||||
var tween:Tween = event.target as Tween;
|
||||
if (tween && tween.isComplete)
|
||||
addWithID(tween.nextTween, objectID);
|
||||
}
|
||||
}
|
||||
|
||||
private static function getNextID():uint { return ++sCurrentObjectID; }
|
||||
|
||||
/** The total life time of the juggler (in seconds). */
|
||||
public function get elapsedTime():Number { return _elapsedTime; }
|
||||
|
||||
/** The scale at which the time is passing. This can be used for slow motion or time laps
|
||||
* effects. Values below '1' will make all animations run slower, values above '1' faster.
|
||||
* @default 1.0 */
|
||||
public function get timeScale():Number { return _timeScale; }
|
||||
public function set timeScale(value:Number):void { _timeScale = value; }
|
||||
|
||||
/** The actual vector that contains all objects that are currently being animated. */
|
||||
protected function get objects():Vector.<IAnimatable> { return _objects; }
|
||||
}
|
||||
}
|
||||
233
mobile_version/src/starling/animation/Transitions.as
Normal file
233
mobile_version/src/starling/animation/Transitions.as
Normal file
@@ -0,0 +1,233 @@
|
||||
// =================================================================================================
|
||||
//
|
||||
// Starling Framework
|
||||
// Copyright Gamua GmbH. All Rights Reserved.
|
||||
//
|
||||
// This program is free software. You can redistribute and/or modify it
|
||||
// in accordance with the terms of the accompanying license agreement.
|
||||
//
|
||||
// =================================================================================================
|
||||
//
|
||||
// easing functions thankfully taken from http://dojotoolkit.org
|
||||
// and http://www.robertpenner.com/easing
|
||||
//
|
||||
|
||||
package starling.animation
|
||||
{
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
import starling.errors.AbstractClassError;
|
||||
|
||||
/** The Transitions class contains static methods that define easing functions.
|
||||
* Those functions are used by the Tween class to execute animations.
|
||||
*
|
||||
* <p>Here is a visual representation of the available transitions:</p>
|
||||
* <img src="http://gamua.com/img/blog/2010/sparrow-transitions.png"/>
|
||||
*
|
||||
* <p>You can define your own transitions through the "registerTransition" function. A
|
||||
* transition function must have the following signature, where <code>ratio</code> is
|
||||
* in the range 0-1:</p>
|
||||
*
|
||||
* <pre>function myTransition(ratio:Number):Number</pre>
|
||||
*/
|
||||
public class Transitions
|
||||
{
|
||||
public static const LINEAR:String = "linear";
|
||||
public static const EASE_IN:String = "easeIn";
|
||||
public static const EASE_OUT:String = "easeOut";
|
||||
public static const EASE_IN_OUT:String = "easeInOut";
|
||||
public static const EASE_OUT_IN:String = "easeOutIn";
|
||||
public static const EASE_IN_BACK:String = "easeInBack";
|
||||
public static const EASE_OUT_BACK:String = "easeOutBack";
|
||||
public static const EASE_IN_OUT_BACK:String = "easeInOutBack";
|
||||
public static const EASE_OUT_IN_BACK:String = "easeOutInBack";
|
||||
public static const EASE_IN_ELASTIC:String = "easeInElastic";
|
||||
public static const EASE_OUT_ELASTIC:String = "easeOutElastic";
|
||||
public static const EASE_IN_OUT_ELASTIC:String = "easeInOutElastic";
|
||||
public static const EASE_OUT_IN_ELASTIC:String = "easeOutInElastic";
|
||||
public static const EASE_IN_BOUNCE:String = "easeInBounce";
|
||||
public static const EASE_OUT_BOUNCE:String = "easeOutBounce";
|
||||
public static const EASE_IN_OUT_BOUNCE:String = "easeInOutBounce";
|
||||
public static const EASE_OUT_IN_BOUNCE:String = "easeOutInBounce";
|
||||
|
||||
private static var sTransitions:Dictionary;
|
||||
|
||||
/** @private */
|
||||
public function Transitions() { throw new AbstractClassError(); }
|
||||
|
||||
/** Returns the transition function that was registered under a certain name. */
|
||||
public static function getTransition(name:String):Function
|
||||
{
|
||||
if (sTransitions == null) registerDefaults();
|
||||
return sTransitions[name];
|
||||
}
|
||||
|
||||
/** Registers a new transition function under a certain name. */
|
||||
public static function register(name:String, func:Function):void
|
||||
{
|
||||
if (sTransitions == null) registerDefaults();
|
||||
sTransitions[name] = func;
|
||||
}
|
||||
|
||||
private static function registerDefaults():void
|
||||
{
|
||||
sTransitions = new Dictionary();
|
||||
|
||||
register(LINEAR, linear);
|
||||
register(EASE_IN, easeIn);
|
||||
register(EASE_OUT, easeOut);
|
||||
register(EASE_IN_OUT, easeInOut);
|
||||
register(EASE_OUT_IN, easeOutIn);
|
||||
register(EASE_IN_BACK, easeInBack);
|
||||
register(EASE_OUT_BACK, easeOutBack);
|
||||
register(EASE_IN_OUT_BACK, easeInOutBack);
|
||||
register(EASE_OUT_IN_BACK, easeOutInBack);
|
||||
register(EASE_IN_ELASTIC, easeInElastic);
|
||||
register(EASE_OUT_ELASTIC, easeOutElastic);
|
||||
register(EASE_IN_OUT_ELASTIC, easeInOutElastic);
|
||||
register(EASE_OUT_IN_ELASTIC, easeOutInElastic);
|
||||
register(EASE_IN_BOUNCE, easeInBounce);
|
||||
register(EASE_OUT_BOUNCE, easeOutBounce);
|
||||
register(EASE_IN_OUT_BOUNCE, easeInOutBounce);
|
||||
register(EASE_OUT_IN_BOUNCE, easeOutInBounce);
|
||||
}
|
||||
|
||||
// transition functions
|
||||
|
||||
protected static function linear(ratio:Number):Number
|
||||
{
|
||||
return ratio;
|
||||
}
|
||||
|
||||
protected static function easeIn(ratio:Number):Number
|
||||
{
|
||||
return ratio * ratio * ratio;
|
||||
}
|
||||
|
||||
protected static function easeOut(ratio:Number):Number
|
||||
{
|
||||
var invRatio:Number = ratio - 1.0;
|
||||
return invRatio * invRatio * invRatio + 1;
|
||||
}
|
||||
|
||||
protected static function easeInOut(ratio:Number):Number
|
||||
{
|
||||
return easeCombined(easeIn, easeOut, ratio);
|
||||
}
|
||||
|
||||
protected static function easeOutIn(ratio:Number):Number
|
||||
{
|
||||
return easeCombined(easeOut, easeIn, ratio);
|
||||
}
|
||||
|
||||
protected static function easeInBack(ratio:Number):Number
|
||||
{
|
||||
var s:Number = 1.70158;
|
||||
return Math.pow(ratio, 2) * ((s + 1.0)*ratio - s);
|
||||
}
|
||||
|
||||
protected static function easeOutBack(ratio:Number):Number
|
||||
{
|
||||
var invRatio:Number = ratio - 1.0;
|
||||
var s:Number = 1.70158;
|
||||
return Math.pow(invRatio, 2) * ((s + 1.0)*invRatio + s) + 1.0;
|
||||
}
|
||||
|
||||
protected static function easeInOutBack(ratio:Number):Number
|
||||
{
|
||||
return easeCombined(easeInBack, easeOutBack, ratio);
|
||||
}
|
||||
|
||||
protected static function easeOutInBack(ratio:Number):Number
|
||||
{
|
||||
return easeCombined(easeOutBack, easeInBack, ratio);
|
||||
}
|
||||
|
||||
protected static function easeInElastic(ratio:Number):Number
|
||||
{
|
||||
if (ratio == 0 || ratio == 1) return ratio;
|
||||
else
|
||||
{
|
||||
var p:Number = 0.3;
|
||||
var s:Number = p/4.0;
|
||||
var invRatio:Number = ratio - 1;
|
||||
return -1.0 * Math.pow(2.0, 10.0*invRatio) * Math.sin((invRatio-s)*(2.0*Math.PI)/p);
|
||||
}
|
||||
}
|
||||
|
||||
protected static function easeOutElastic(ratio:Number):Number
|
||||
{
|
||||
if (ratio == 0 || ratio == 1) return ratio;
|
||||
else
|
||||
{
|
||||
var p:Number = 0.3;
|
||||
var s:Number = p/4.0;
|
||||
return Math.pow(2.0, -10.0*ratio) * Math.sin((ratio-s)*(2.0*Math.PI)/p) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
protected static function easeInOutElastic(ratio:Number):Number
|
||||
{
|
||||
return easeCombined(easeInElastic, easeOutElastic, ratio);
|
||||
}
|
||||
|
||||
protected static function easeOutInElastic(ratio:Number):Number
|
||||
{
|
||||
return easeCombined(easeOutElastic, easeInElastic, ratio);
|
||||
}
|
||||
|
||||
protected static function easeInBounce(ratio:Number):Number
|
||||
{
|
||||
return 1.0 - easeOutBounce(1.0 - ratio);
|
||||
}
|
||||
|
||||
protected static function easeOutBounce(ratio:Number):Number
|
||||
{
|
||||
var s:Number = 7.5625;
|
||||
var p:Number = 2.75;
|
||||
var l:Number;
|
||||
if (ratio < (1.0/p))
|
||||
{
|
||||
l = s * Math.pow(ratio, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ratio < (2.0/p))
|
||||
{
|
||||
ratio -= 1.5/p;
|
||||
l = s * Math.pow(ratio, 2) + 0.75;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ratio < 2.5/p)
|
||||
{
|
||||
ratio -= 2.25/p;
|
||||
l = s * Math.pow(ratio, 2) + 0.9375;
|
||||
}
|
||||
else
|
||||
{
|
||||
ratio -= 2.625/p;
|
||||
l = s * Math.pow(ratio, 2) + 0.984375;
|
||||
}
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
protected static function easeInOutBounce(ratio:Number):Number
|
||||
{
|
||||
return easeCombined(easeInBounce, easeOutBounce, ratio);
|
||||
}
|
||||
|
||||
protected static function easeOutInBounce(ratio:Number):Number
|
||||
{
|
||||
return easeCombined(easeOutBounce, easeInBounce, ratio);
|
||||
}
|
||||
|
||||
protected static function easeCombined(startFunc:Function, endFunc:Function, ratio:Number):Number
|
||||
{
|
||||
if (ratio < 0.5) return 0.5 * startFunc(ratio*2.0);
|
||||
else return 0.5 * endFunc((ratio-0.5)*2.0) + 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
451
mobile_version/src/starling/animation/Tween.as
Normal file
451
mobile_version/src/starling/animation/Tween.as
Normal file
@@ -0,0 +1,451 @@
|
||||
// =================================================================================================
|
||||
//
|
||||
// Starling Framework
|
||||
// Copyright Gamua GmbH. All Rights Reserved.
|
||||
//
|
||||
// This program is free software. You can redistribute and/or modify it
|
||||
// in accordance with the terms of the accompanying license agreement.
|
||||
//
|
||||
// =================================================================================================
|
||||
|
||||
|
||||
package starling.animation
|
||||
{
|
||||
import starling.core.starling_internal;
|
||||
import starling.events.Event;
|
||||
import starling.events.EventDispatcher;
|
||||
import starling.utils.Color;
|
||||
|
||||
/** A Tween animates numeric properties of objects. It uses different transition functions
|
||||
* to give the animations various styles.
|
||||
*
|
||||
* <p>The primary use of this class is to do standard animations like movement, fading,
|
||||
* rotation, etc. But there are no limits on what to animate; as long as the property you want
|
||||
* to animate is numeric (<code>int, uint, Number</code>), the tween can handle it. For a list
|
||||
* of available Transition types, look at the "Transitions" class.</p>
|
||||
*
|
||||
* <p>Here is an example of a tween that moves an object to the right, rotates it, and
|
||||
* fades it out:</p>
|
||||
*
|
||||
* <listing>
|
||||
* var tween:Tween = new Tween(object, 2.0, Transitions.EASE_IN_OUT);
|
||||
* tween.animate("x", object.x + 50);
|
||||
* tween.animate("rotation", deg2rad(45));
|
||||
* tween.fadeTo(0); // equivalent to 'animate("alpha", 0)'
|
||||
* Starling.juggler.add(tween);</listing>
|
||||
*
|
||||
* <p>Note that the object is added to a juggler at the end of this sample. That's because a
|
||||
* tween will only be executed if its "advanceTime" method is executed regularly - the
|
||||
* juggler will do that for you, and will remove the tween when it is finished.</p>
|
||||
*
|
||||
* @see Juggler
|
||||
* @see Transitions
|
||||
*/
|
||||
public class Tween extends EventDispatcher implements IAnimatable
|
||||
{
|
||||
private static const HINT_MARKER:String = '#';
|
||||
|
||||
private var _target:Object;
|
||||
private var _transitionFunc:Function;
|
||||
private var _transitionName:String;
|
||||
|
||||
private var _properties:Vector.<String>;
|
||||
private var _startValues:Vector.<Number>;
|
||||
private var _endValues:Vector.<Number>;
|
||||
private var _updateFuncs:Vector.<Function>;
|
||||
|
||||
private var _onStart:Function;
|
||||
private var _onUpdate:Function;
|
||||
private var _onRepeat:Function;
|
||||
private var _onComplete:Function;
|
||||
|
||||
private var _onStartArgs:Array;
|
||||
private var _onUpdateArgs:Array;
|
||||
private var _onRepeatArgs:Array;
|
||||
private var _onCompleteArgs:Array;
|
||||
|
||||
private var _totalTime:Number;
|
||||
private var _currentTime:Number;
|
||||
private var _progress:Number;
|
||||
private var _delay:Number;
|
||||
private var _roundToInt:Boolean;
|
||||
private var _nextTween:Tween;
|
||||
private var _repeatCount:int;
|
||||
private var _repeatDelay:Number;
|
||||
private var _reverse:Boolean;
|
||||
private var _currentCycle:int;
|
||||
|
||||
/** Creates a tween with a target, duration (in seconds) and a transition function.
|
||||
* @param target the object that you want to animate
|
||||
* @param time the duration of the Tween (in seconds)
|
||||
* @param transition can be either a String (e.g. one of the constants defined in the
|
||||
* Transitions class) or a function. Look up the 'Transitions' class for a
|
||||
* documentation about the required function signature. */
|
||||
public function Tween(target:Object, time:Number, transition:Object="linear")
|
||||
{
|
||||
reset(target, time, transition);
|
||||
}
|
||||
|
||||
/** Resets the tween to its default values. Useful for pooling tweens. */
|
||||
public function reset(target:Object, time:Number, transition:Object="linear"):Tween
|
||||
{
|
||||
_target = target;
|
||||
_currentTime = 0.0;
|
||||
_totalTime = Math.max(0.0001, time);
|
||||
_progress = 0.0;
|
||||
_delay = _repeatDelay = 0.0;
|
||||
_onStart = _onUpdate = _onRepeat = _onComplete = null;
|
||||
_onStartArgs = _onUpdateArgs = _onRepeatArgs = _onCompleteArgs = null;
|
||||
_roundToInt = _reverse = false;
|
||||
_repeatCount = 1;
|
||||
_currentCycle = -1;
|
||||
_nextTween = null;
|
||||
|
||||
if (transition is String)
|
||||
this.transition = transition as String;
|
||||
else if (transition is Function)
|
||||
this.transitionFunc = transition as Function;
|
||||
else
|
||||
throw new ArgumentError("Transition must be either a string or a function");
|
||||
|
||||
if (_properties) _properties.length = 0; else _properties = new <String>[];
|
||||
if (_startValues) _startValues.length = 0; else _startValues = new <Number>[];
|
||||
if (_endValues) _endValues.length = 0; else _endValues = new <Number>[];
|
||||
if (_updateFuncs) _updateFuncs.length = 0; else _updateFuncs = new <Function>[];
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Animates the property of the target to a certain value. You can call this method
|
||||
* multiple times on one tween.
|
||||
*
|
||||
* <p>Some property types are handled in a special way:</p>
|
||||
* <ul>
|
||||
* <li>If the property contains the string <code>color</code> or <code>Color</code>,
|
||||
* it will be treated as an unsigned integer with a color value
|
||||
* (e.g. <code>0xff0000</code> for red). Each color channel will be animated
|
||||
* individually.</li>
|
||||
* <li>The same happens if you append the string <code>#rgb</code> to the name.</li>
|
||||
* <li>If you append <code>#rad</code>, the property is treated as an angle in radians,
|
||||
* making sure it always uses the shortest possible arc for the rotation.</li>
|
||||
* <li>The string <code>#deg</code> does the same for angles in degrees.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public function animate(property:String, endValue:Number):void
|
||||
{
|
||||
if (_target == null) return; // tweening null just does nothing.
|
||||
|
||||
var pos:int = _properties.length;
|
||||
var updateFunc:Function = getUpdateFuncFromProperty(property);
|
||||
|
||||
_properties[pos] = getPropertyName(property);
|
||||
_startValues[pos] = Number.NaN;
|
||||
_endValues[pos] = endValue;
|
||||
_updateFuncs[pos] = updateFunc;
|
||||
}
|
||||
|
||||
/** Animates the 'scaleX' and 'scaleY' properties of an object simultaneously. */
|
||||
public function scaleTo(factor:Number):void
|
||||
{
|
||||
animate("scaleX", factor);
|
||||
animate("scaleY", factor);
|
||||
}
|
||||
|
||||
/** Animates the 'x' and 'y' properties of an object simultaneously. */
|
||||
public function moveTo(x:Number, y:Number):void
|
||||
{
|
||||
animate("x", x);
|
||||
animate("y", y);
|
||||
}
|
||||
|
||||
/** Animates the 'alpha' property of an object to a certain target value. */
|
||||
public function fadeTo(alpha:Number):void
|
||||
{
|
||||
animate("alpha", alpha);
|
||||
}
|
||||
|
||||
/** Animates the 'rotation' property of an object to a certain target value, using the
|
||||
* smallest possible arc. 'type' may be either 'rad' or 'deg', depending on the unit of
|
||||
* measurement. */
|
||||
public function rotateTo(angle:Number, type:String="rad"):void
|
||||
{
|
||||
animate("rotation#" + type, angle);
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
public function advanceTime(time:Number):void
|
||||
{
|
||||
if (time == 0 || (_repeatCount == 1 && _currentTime == _totalTime)) return;
|
||||
|
||||
var i:int;
|
||||
var previousTime:Number = _currentTime;
|
||||
var restTime:Number = _totalTime - _currentTime;
|
||||
var carryOverTime:Number = time > restTime ? time - restTime : 0.0;
|
||||
|
||||
_currentTime += time;
|
||||
|
||||
if (_currentTime <= 0)
|
||||
return; // the delay is not over yet
|
||||
else if (_currentTime > _totalTime)
|
||||
_currentTime = _totalTime;
|
||||
|
||||
if (_currentCycle < 0 && previousTime <= 0 && _currentTime > 0)
|
||||
{
|
||||
_currentCycle++;
|
||||
if (_onStart != null) _onStart.apply(this, _onStartArgs);
|
||||
}
|
||||
|
||||
var ratio:Number = _currentTime / _totalTime;
|
||||
var reversed:Boolean = _reverse && (_currentCycle % 2 == 1);
|
||||
var numProperties:int = _startValues.length;
|
||||
_progress = reversed ? _transitionFunc(1.0 - ratio) : _transitionFunc(ratio);
|
||||
|
||||
for (i=0; i<numProperties; ++i)
|
||||
{
|
||||
if (_startValues[i] != _startValues[i]) // isNaN check - "isNaN" causes allocation!
|
||||
_startValues[i] = _target[_properties[i]] as Number;
|
||||
|
||||
var updateFunc:Function = _updateFuncs[i] as Function;
|
||||
updateFunc(_properties[i], _startValues[i], _endValues[i]);
|
||||
}
|
||||
|
||||
if (_onUpdate != null)
|
||||
_onUpdate.apply(this, _onUpdateArgs);
|
||||
|
||||
if (previousTime < _totalTime && _currentTime >= _totalTime)
|
||||
{
|
||||
if (_repeatCount == 0 || _repeatCount > 1)
|
||||
{
|
||||
_currentTime = -_repeatDelay;
|
||||
_currentCycle++;
|
||||
if (_repeatCount > 1) _repeatCount--;
|
||||
if (_onRepeat != null) _onRepeat.apply(this, _onRepeatArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
// save callback & args: they might be changed through an event listener
|
||||
var onComplete:Function = _onComplete;
|
||||
var onCompleteArgs:Array = _onCompleteArgs;
|
||||
|
||||
// in the 'onComplete' callback, people might want to call "tween.reset" and
|
||||
// add it to another juggler; so this event has to be dispatched *before*
|
||||
// executing 'onComplete'.
|
||||
dispatchEventWith(Event.REMOVE_FROM_JUGGLER);
|
||||
if (onComplete != null) onComplete.apply(this, onCompleteArgs);
|
||||
if (_currentTime == 0) carryOverTime = 0; // tween was reset
|
||||
}
|
||||
}
|
||||
|
||||
if (carryOverTime)
|
||||
advanceTime(carryOverTime);
|
||||
}
|
||||
|
||||
// animation hints
|
||||
|
||||
private function getUpdateFuncFromProperty(property:String):Function
|
||||
{
|
||||
var updateFunc:Function;
|
||||
var hint:String = getPropertyHint(property);
|
||||
|
||||
switch (hint)
|
||||
{
|
||||
case null: updateFunc = updateStandard; break;
|
||||
case "rgb": updateFunc = updateRgb; break;
|
||||
case "rad": updateFunc = updateRad; break;
|
||||
case "deg": updateFunc = updateDeg; break;
|
||||
default:
|
||||
trace("[Starling] Ignoring unknown property hint:", hint);
|
||||
updateFunc = updateStandard;
|
||||
}
|
||||
|
||||
return updateFunc;
|
||||
}
|
||||
|
||||
/** @private */
|
||||
internal static function getPropertyHint(property:String):String
|
||||
{
|
||||
// colorization is special; it does not require a hint marker, just the word 'color'.
|
||||
if (property.indexOf("color") != -1 || property.indexOf("Color") != -1)
|
||||
return "rgb";
|
||||
|
||||
var hintMarkerIndex:int = property.indexOf(HINT_MARKER);
|
||||
if (hintMarkerIndex != -1) return property.substr(hintMarkerIndex+1);
|
||||
else return null;
|
||||
}
|
||||
|
||||
/** @private */
|
||||
internal static function getPropertyName(property:String):String
|
||||
{
|
||||
var hintMarkerIndex:int = property.indexOf(HINT_MARKER);
|
||||
if (hintMarkerIndex != -1) return property.substring(0, hintMarkerIndex);
|
||||
else return property;
|
||||
}
|
||||
|
||||
private function updateStandard(property:String, startValue:Number, endValue:Number):void
|
||||
{
|
||||
var newValue:Number = startValue + _progress * (endValue - startValue);
|
||||
if (_roundToInt) newValue = Math.round(newValue);
|
||||
_target[property] = newValue;
|
||||
}
|
||||
|
||||
private function updateRgb(property:String, startValue:Number, endValue:Number):void
|
||||
{
|
||||
_target[property] = Color.interpolate(uint(startValue), uint(endValue), _progress);
|
||||
}
|
||||
|
||||
private function updateRad(property:String, startValue:Number, endValue:Number):void
|
||||
{
|
||||
updateAngle(Math.PI, property, startValue, endValue);
|
||||
}
|
||||
|
||||
private function updateDeg(property:String, startValue:Number, endValue:Number):void
|
||||
{
|
||||
updateAngle(180, property, startValue, endValue);
|
||||
}
|
||||
|
||||
private function updateAngle(pi:Number, property:String, startValue:Number, endValue:Number):void
|
||||
{
|
||||
while (Math.abs(endValue - startValue) > pi)
|
||||
{
|
||||
if (startValue < endValue) endValue -= 2.0 * pi;
|
||||
else endValue += 2.0 * pi;
|
||||
}
|
||||
|
||||
updateStandard(property, startValue, endValue);
|
||||
}
|
||||
|
||||
/** The end value a certain property is animated to. Throws an ArgumentError if the
|
||||
* property is not being animated. */
|
||||
public function getEndValue(property:String):Number
|
||||
{
|
||||
var index:int = _properties.indexOf(property);
|
||||
if (index == -1) throw new ArgumentError("The property '" + property + "' is not animated");
|
||||
else return _endValues[index] as Number;
|
||||
}
|
||||
|
||||
/** Indicates if the tween is finished. */
|
||||
public function get isComplete():Boolean
|
||||
{
|
||||
return _currentTime >= _totalTime && _repeatCount == 1;
|
||||
}
|
||||
|
||||
/** The target object that is animated. */
|
||||
public function get target():Object { return _target; }
|
||||
|
||||
/** The transition method used for the animation. @see Transitions */
|
||||
public function get transition():String { return _transitionName; }
|
||||
public function set transition(value:String):void
|
||||
{
|
||||
_transitionName = value;
|
||||
_transitionFunc = Transitions.getTransition(value);
|
||||
|
||||
if (_transitionFunc == null)
|
||||
throw new ArgumentError("Invalid transiton: " + value);
|
||||
}
|
||||
|
||||
/** The actual transition function used for the animation. */
|
||||
public function get transitionFunc():Function { return _transitionFunc; }
|
||||
public function set transitionFunc(value:Function):void
|
||||
{
|
||||
_transitionName = "custom";
|
||||
_transitionFunc = value;
|
||||
}
|
||||
|
||||
/** The total time the tween will take per repetition (in seconds). */
|
||||
public function get totalTime():Number { return _totalTime; }
|
||||
|
||||
/** The time that has passed since the tween was created (in seconds). */
|
||||
public function get currentTime():Number { return _currentTime; }
|
||||
|
||||
/** The current progress between 0 and 1, as calculated by the transition function. */
|
||||
public function get progress():Number { return _progress; }
|
||||
|
||||
/** The delay before the tween is started (in seconds). @default 0 */
|
||||
public function get delay():Number { return _delay; }
|
||||
public function set delay(value:Number):void
|
||||
{
|
||||
_currentTime = _currentTime + _delay - value;
|
||||
_delay = value;
|
||||
}
|
||||
|
||||
/** The number of times the tween will be executed.
|
||||
* Set to '0' to tween indefinitely. @default 1 */
|
||||
public function get repeatCount():int { return _repeatCount; }
|
||||
public function set repeatCount(value:int):void { _repeatCount = value; }
|
||||
|
||||
/** The amount of time to wait between repeat cycles (in seconds). @default 0 */
|
||||
public function get repeatDelay():Number { return _repeatDelay; }
|
||||
public function set repeatDelay(value:Number):void { _repeatDelay = value; }
|
||||
|
||||
/** Indicates if the tween should be reversed when it is repeating. If enabled,
|
||||
* every second repetition will be reversed. @default false */
|
||||
public function get reverse():Boolean { return _reverse; }
|
||||
public function set reverse(value:Boolean):void { _reverse = value; }
|
||||
|
||||
/** Indicates if the numeric values should be cast to Integers. @default false */
|
||||
public function get roundToInt():Boolean { return _roundToInt; }
|
||||
public function set roundToInt(value:Boolean):void { _roundToInt = value; }
|
||||
|
||||
/** A function that will be called when the tween starts (after a possible delay). */
|
||||
public function get onStart():Function { return _onStart; }
|
||||
public function set onStart(value:Function):void { _onStart = value; }
|
||||
|
||||
/** A function that will be called each time the tween is advanced. */
|
||||
public function get onUpdate():Function { return _onUpdate; }
|
||||
public function set onUpdate(value:Function):void { _onUpdate = value; }
|
||||
|
||||
/** A function that will be called each time the tween finishes one repetition
|
||||
* (except the last, which will trigger 'onComplete'). */
|
||||
public function get onRepeat():Function { return _onRepeat; }
|
||||
public function set onRepeat(value:Function):void { _onRepeat = value; }
|
||||
|
||||
/** A function that will be called when the tween is complete. */
|
||||
public function get onComplete():Function { return _onComplete; }
|
||||
public function set onComplete(value:Function):void { _onComplete = value; }
|
||||
|
||||
/** The arguments that will be passed to the 'onStart' function. */
|
||||
public function get onStartArgs():Array { return _onStartArgs; }
|
||||
public function set onStartArgs(value:Array):void { _onStartArgs = value; }
|
||||
|
||||
/** The arguments that will be passed to the 'onUpdate' function. */
|
||||
public function get onUpdateArgs():Array { return _onUpdateArgs; }
|
||||
public function set onUpdateArgs(value:Array):void { _onUpdateArgs = value; }
|
||||
|
||||
/** The arguments that will be passed to the 'onRepeat' function. */
|
||||
public function get onRepeatArgs():Array { return _onRepeatArgs; }
|
||||
public function set onRepeatArgs(value:Array):void { _onRepeatArgs = value; }
|
||||
|
||||
/** The arguments that will be passed to the 'onComplete' function. */
|
||||
public function get onCompleteArgs():Array { return _onCompleteArgs; }
|
||||
public function set onCompleteArgs(value:Array):void { _onCompleteArgs = value; }
|
||||
|
||||
/** Another tween that will be started (i.e. added to the same juggler) as soon as
|
||||
* this tween is completed. */
|
||||
public function get nextTween():Tween { return _nextTween; }
|
||||
public function set nextTween(value:Tween):void { _nextTween = value; }
|
||||
|
||||
// tween pooling
|
||||
|
||||
private static var sTweenPool:Vector.<Tween> = new <Tween>[];
|
||||
|
||||
/** @private */
|
||||
starling_internal static function fromPool(target:Object, time:Number,
|
||||
transition:Object="linear"):Tween
|
||||
{
|
||||
if (sTweenPool.length) return sTweenPool.pop().reset(target, time, transition);
|
||||
else return new Tween(target, time, transition);
|
||||
}
|
||||
|
||||
/** @private */
|
||||
starling_internal static function toPool(tween:Tween):void
|
||||
{
|
||||
// reset any object-references, to make sure we don't prevent any garbage collection
|
||||
tween._onStart = tween._onUpdate = tween._onRepeat = tween._onComplete = null;
|
||||
tween._onStartArgs = tween._onUpdateArgs = tween._onRepeatArgs = tween._onCompleteArgs = null;
|
||||
tween._target = null;
|
||||
tween._transitionFunc = null;
|
||||
tween.removeEventListeners();
|
||||
sTweenPool.push(tween);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user