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

Add FlxTween.shake for sprite shaking. #2549

Merged
merged 3 commits into from
May 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions flixel/tweens/FlxTween.hx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package flixel.tweens;

import flixel.tweens.misc.ShakeTween;
import flixel.util.FlxAxes;
import flixel.FlxG;
import flixel.FlxObject;
import flixel.FlxSprite;
Expand Down Expand Up @@ -130,6 +132,26 @@ class FlxTween implements IFlxDestroyable
return globalManager.num(FromValue, ToValue, Duration, Options, TweenFunction);
}

/**
* A simple shake effect for FlxSprite. Shorthand for creating a ShakeTween, starting it and adding it to the TweenManager.
*
* ```haxe
* FlxTween.shake(Sprite, 0.1, 2, FlxAxes.XY, { ease: easeFunction, onStart: onStart, onUpdate: onUpdate, onComplete: onComplete, type: ONESHOT });
* ```
*
* @param Sprite Sprite to shake.
* @param Intensity Percentage representing the maximum distance
* that the sprite can move while shaking.
* @param Duration The length in seconds that the shaking effect should last.
* @param Axes On what axes to shake. Default value is `FlxAxes.XY` / both.
* @param Options A structure with tween options.
* @return The added ShakeTween object.
*/
public static function shake(Sprite:FlxSprite, Intensity:Float = 0.05, Duration:Float = 1, ?Axes:FlxAxes, ?Options:TweenOptions):ShakeTween
{
return globalManager.shake(Sprite, Intensity, Duration, Axes, Options);
}

/**
* Tweens numeric value which represents angle. Shorthand for creating a AngleTween object, starting it and adding it to the TweenManager.
*
Expand Down Expand Up @@ -857,6 +879,27 @@ class FlxTweenManager extends FlxBasic
return add(tween);
}

/**
* A simple shake effect for FlxSprite. Shorthand for creating a ShakeTween, starting it and adding it to the TweenManager.
*
* ```haxe
* FlxTween.shake(Sprite, 0.1, 2, FlxAxes.XY, { ease: easeFunction, onStart: onStart, onUpdate: onUpdate, onComplete: onComplete, type: ONESHOT });
* ```
*
* @param Sprite Sprite to shake.
* @param Intensity Percentage representing the maximum distance
* that the sprite can move while shaking.
* @param Duration The length in seconds that the shaking effect should last.
* @param Axes On what axes to shake. Default value is `FlxAxes.XY` / both.
* @param Options A structure with tween options.
*/
public function shake(Sprite:FlxSprite, Intensity:Float = 0.05, Duration:Float = 1, ?Axes:FlxAxes = XY, ?Options:TweenOptions):ShakeTween
{
var tween = new ShakeTween(Options, this);
tween.tween(Sprite, Intensity, Duration, Axes);
return add(tween);
}

/**
* Tweens numeric value which represents angle. Shorthand for creating a AngleTween object, starting it and adding it to the TweenManager.
*
Expand Down
75 changes: 75 additions & 0 deletions flixel/tweens/misc/ShakeTween.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package flixel.tweens.misc;

import flixel.math.FlxPoint;
import flixel.util.FlxAxes;

/**
* Shake effect for a FlxSprite
*/
class ShakeTween extends FlxTween
{
/**
* Percentage representing the maximum distance that the object can move while shaking.
*/
var intensity:Float;

/**
* Defines on what axes to `shake()`. Default value is `XY` / both.
*/
var axes:FlxAxes;

/**
* The sprite to shake.
*/
var sprite:FlxSprite;

/**
* Defines the initial offset of the sprite at the beginning of the shake effect.
*/
var initialOffset:FlxPoint;

/**
* A simple shake effect for FlxSprite.
*
* @param Sprite Sprite to shake.
* @param Intensity Percentage representing the maximum distance
* that the sprite can move while shaking.
* @param Duration The length in seconds that the shaking effect should last.
* @param Axes On what axes to shake. Default value is `FlxAxes.XY` / both.
*/
public function tween(Sprite:FlxSprite, Intensity:Float = 0.05, Duration:Float = 1, Axes:FlxAxes = XY):ShakeTween
{
intensity = Intensity;
sprite = Sprite;
duration = Duration;
axes = Axes;
initialOffset = new FlxPoint(Sprite.offset.x, Sprite.offset.y);
start();
return this;
}

override function destroy():Void
{
super.destroy();
// Return the sprite to its initial offset.
if (sprite != null && !sprite.offset.equals(initialOffset))
sprite.offset.set(initialOffset.x, initialOffset.y);

sprite = null;
initialOffset = null;
}

override function update(elapsed:Float)
{
super.update(elapsed);
if (axes != Y)
sprite.offset.x = initialOffset.x + FlxG.random.float(-intensity * sprite.width, intensity * sprite.width);
if (axes != X)
sprite.offset.y = initialOffset.y + FlxG.random.float(-intensity * sprite.height, intensity * sprite.height);
}

override function isTweenOf(Object:Dynamic, ?Field:String):Bool
{
return sprite == Object && (Field == null || Field == "shake");
}
}
24 changes: 24 additions & 0 deletions tests/unit/src/flixel/tweens/FlxTweenTest.hx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package flixel.tweens;

import flixel.math.FlxPoint;
import flixel.tweens.FlxTween.TweenCallback;
import flixel.util.FlxTimer;
import massive.munit.Assert;
Expand Down Expand Up @@ -212,6 +213,29 @@ class FlxTweenTest extends FlxTest
};
}

@Test
function testCancelShakeTween()
{
var spriteTest = new FlxSprite();
var initialOffset = new FlxPoint(0, 0);
var shakeTween = FlxTween.shake(spriteTest, 1, 0.1);
step();
shakeTween.cancel();
Assert.isTrue(shakeTween.finished);
Assert.isTrue(spriteTest.offset.equals(initialOffset));
}

@Test
function testCompleteShakeTween()
{
var spriteTest = new FlxSprite();
var initialOffset = new FlxPoint(0, 0);
var shakeTween = FlxTween.shake(spriteTest, 1, 0.01);
step(10);
Assert.isTrue(shakeTween.finished);
Assert.isTrue(spriteTest.offset.equals(initialOffset));
}

@Test
function testCompleteAll()
{
Expand Down