Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlxTween: add .wait(), and .then() for chaining, closes #1064 #1614

Merged
merged 14 commits into from
Oct 4, 2015
139 changes: 135 additions & 4 deletions flixel/tweens/FlxTween.hx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import flixel.FlxG;
import flixel.FlxObject;
import flixel.FlxSprite;
import flixel.tweens.FlxEase.EaseFunction;
import flixel.tweens.FlxTween.ThenCommand;
import flixel.tweens.FlxTween.TweenOptions;
import flixel.tweens.FlxTween.TweenMethod;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of doubt this compiles anymore with TweenMethod removed. ;)

import flixel.tweens.misc.AngleTween;
import flixel.tweens.misc.ColorTween;
import flixel.tweens.misc.NumTween;
Expand Down Expand Up @@ -373,7 +376,8 @@ class FlxTween implements IFlxDestroyable
private var _delayToUse:Float = 0;
private var _running:Bool = false;
private var _waitingForRestart:Bool = false;

private var _thens:Array<ThenCommand>;

/**
* This function is called when tween is created, or recycled.
*/
Expand Down Expand Up @@ -406,8 +410,61 @@ class FlxTween implements IFlxDestroyable
onUpdate = null;
onComplete = null;
ease = null;
_thens = null;
}


/**
* After this tween has finished, do this tween next
* @param method
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well delete these empty @param tags, especially considering they're out of sync with the method signature.

* @param params
* @return
*/

public function then(Tween:FlxTween):FlxTween
{
Tween.cancelSoft();
if (_thens == null)
{
_thens = [];
}
_thens.push(new ThenCommand(0, Tween));
return this;
}

/**
* After this tween has finished, wait this many seconds, then do the next chained "then" command
* @param Delay The number of seconds to wait
* @return
*/
public function wait(Delay:Float):FlxTween
{
if (_thens == null)
{
_thens = [];
}
_thens.push(new ThenCommand(Delay, null));
return this;
}

/**
* Add a delay and a chained tween in the same command
* @param Delay
* @param method
* @param params
* @return
*/
public function waitThen(Delay:Float, Tween:FlxTween):FlxTween
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there really much of a point to this combined function? It doesn't really add anything, and it's not really shorter either. Compare:

wait(1).then(tween)
waitThen(1, tween)

The first one seems more readable to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that's fine. One less function to maintain.

{
if (_thens == null)
{
_thens = [];
}

_thens.push(new ThenCommand(Delay, null));
_thens.push(new ThenCommand(0 , Tween));
return this;
}

private function update(elapsed:Float):Void
{
_secondsSinceStart += elapsed;
Expand Down Expand Up @@ -472,6 +529,14 @@ class FlxTween implements IFlxDestroyable
manager.remove(this);
}

private function cancelSoft():Void
{
active = false;
_running = false;
finished = true;
manager.removeSoft(this);
}

private function finish():Void
{
executions++;
Expand Down Expand Up @@ -523,6 +588,39 @@ class FlxTween implements IFlxDestroyable
active = false;
_running = false;
finished = true;

if (_thens != null && _thens.length > 0)
{
var then = _thens[0];

_thens.splice(0, 1);

if (then.delay <= 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it might fail with wait(0) (which should just be "no wait" - doesn't make sense if written like that but the delay could be dynamically set from some variable that happens to become 0 at some point)? And what's the expected result for negative values?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Working on it...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right you were, it needs to call onEnd() again in the case that delay is <= 0 AND the tween is null, signifying it's a delay that should terminate instantly and run the next "then" command.

{
if (then.tween != null)
{
doNextTween(then.tween, _thens);
}
}
else
{
doNextTween(FlxTween.num(0,0,then.delay), _thens);
}
_thens = null;
}
}

private function doNextTween(tween:FlxTween, thens:Array<ThenCommand>):Void
{
if (!tween.active)
{
tween.start();
manager.add(tween);
}
if (thens != null)
{
tween._thens = _thens;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, didn't know Haxe allowed a trailing comma here for the last element. :)


/**
Expand Down Expand Up @@ -621,7 +719,7 @@ typedef TweenOptions = {
?onUpdate:TweenCallback,
?onComplete:TweenCallback,
?startDelay:Null<Float>,
?loopDelay:Null<Float>,
?loopDelay:Null<Float>
}

@:access(flixel.tweens.FlxTween)
Expand Down Expand Up @@ -705,7 +803,6 @@ class FlxTweenManager extends FlxBasic
* Remove a FlxTween.
*
* @param Tween The FlxTween to remove.
* @param Destroy Whether you want to destroy the FlxTween.
* @return The added FlxTween object.
*/
@:allow(flixel.tweens.FlxTween)
Expand All @@ -723,6 +820,28 @@ class FlxTweenManager extends FlxBasic

return Tween;
}

/**
* Remove a FlxTween without destroying it
*
* @param Tween The FlxTween to remove.
* @param Destroy Whether you want to destroy the FlxTween.
* @return The added FlxTween object.
*/
@:allow(flixel.tweens.FlxTween)
private function removeSoft(Tween:FlxTween):FlxTween
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might make sense to bring back the Destroy flag to the original remove() considering this is a 1:1 copy of it other than that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kay

{
if (Tween == null)
{
return null;
}

Tween.active = false;

FlxArrayUtil.fastSplice(_tweens, Tween);

return Tween;
}

/**
* Removes all FlxTweens.
Expand All @@ -735,3 +854,15 @@ class FlxTweenManager extends FlxBasic
}
}
}

class ThenCommand
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I like the name ThenCommand. ChainedTween maybe? That doesn't really cover the wait use-case though.. ChainedCommand? ChainedAction?

Thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, there's not really any reason to expose this API to the user, would mean we have to worry about backwards compatibilty etc. Should be a private class.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChainedTween is fine.

{
public var delay:Float;
public var tween:FlxTween;

public function new(Delay:Float, Tween:FlxTween)
{
delay = Delay;
tween = Tween;
}
}
7 changes: 7 additions & 0 deletions flixel/tweens/misc/VarTween.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package flixel.tweens.misc;

import flixel.tweens.FlxTween;
import flixel.util.FlxArrayUtil;
import flixel.util.FlxTimer;

/**
* Tweens multiple numeric public properties of an Object simultaneously.
Expand Down Expand Up @@ -60,6 +61,12 @@ class VarTween extends FlxTween
return this;
}

@:access(flixel.tweens.FlxTween)
override function onEnd():Void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This override doesn't look like it does anything anymore?

{
super.onEnd();
}

override private function update(elapsed:Float):Void
{
var delay:Float = (executions > 0) ? loopDelay : startDelay;
Expand Down