Skip to content

Commit

Permalink
Show transitions above everything else (#410)
Browse files Browse the repository at this point in the history
* Added a camera for the transition substrate

* `Std.int` oops.

* Actually

* Update Transition.hx

* Oops

* Not really fixing the issue

* add camera on transition start

* prevent double camera removal on state switch

* set camera color on creation

* prevent double destroy on camera

* Update Transition.hx

* change hxformat to match flixel's

* cleanup imports

* move top camera logic to TransitionEffect, use modes

* lower case args

* more docs

---------

Co-authored-by: George FunBook <gkurelic@gmail.com>
  • Loading branch information
MAJigsaw77 and Geokureli authored Nov 16, 2023
1 parent a9f4f8e commit 105f37a
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 51 deletions.
56 changes: 32 additions & 24 deletions flixel/addons/transition/Transition.hx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package flixel.addons.transition;

import flixel.addons.transition.TransitionData.TransitionType;
import flixel.addons.transition.TransitionData;
import flixel.addons.transition.TransitionEffect;
import flixel.addons.transition.TransitionFade;
import flixel.addons.transition.TransitionTiles;
import flixel.addons.transition.FlxTransitionSprite.TransitionStatus;
import flixel.addons.transition.FlxTransitionSprite;
import flixel.FlxCamera;
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.FlxSubState;
Expand All @@ -13,6 +14,7 @@ import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import flixel.util.FlxDestroyUtil;
import flixel.util.FlxTimer;

/**
Expand All @@ -23,63 +25,69 @@ import flixel.util.FlxTimer;
class Transition extends FlxSubState
{
public var finishCallback(get, set):Void->Void;

var _effect:TransitionEffect;

public function new(data:TransitionData)
{
super(FlxColor.TRANSPARENT);

_effect = createEffect(data);
_effect.scrollFactor.set(0, 0);
add(_effect);
}

public override function destroy():Void
{
super.destroy();

finishCallback = null;
_effect = null;

_effect = FlxDestroyUtil.destroy(_effect);
}

public function start(NewStatus:TransitionStatus):Void
public function start(newStatus:TransitionStatus):Void
{
_effect.start(NewStatus);
_effect.start(newStatus);
}

public function setStatus(NewStatus:TransitionStatus):Void
public function setStatus(newStatus:TransitionStatus):Void
{
_effect.setStatus(NewStatus);
_effect.setStatus(newStatus);
}

function createEffect(Data:TransitionData):TransitionEffect
function createEffect(data:TransitionData):TransitionEffect
{
switch (Data.type)
switch (data.type)
{
case TransitionType.TILES:
return new TransitionTiles(Data);
return new TransitionTiles(data);
case TransitionType.FADE:
return new TransitionFade(Data);
default:
return null;
return new TransitionFade(data);
case TransitionType.NONE:
throw "Unexpected TransitionType: NONE";
}
}

function get_finishCallback():Void->Void
{
if (_effect != null)
{
return _effect.finishCallback;
}

return null;
}

function set_finishCallback(f:Void->Void):Void->Void
function set_finishCallback(callback:Void->Void):Void->Void
{
if (_effect != null)
{
_effect.finishCallback = f;
return f;
_effect.finishCallback = callback;

return callback;
}

return null;
}
}
78 changes: 63 additions & 15 deletions flixel/addons/transition/TransitionData.hx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@ enum abstract TransitionType(String)
var FADE = "fade";
}

/**
* Whether this transition will use a new camera, the top camera, or the default camera(s)
* @since 5.6.0
*/
enum TransitionCameraMode
{
/** The transition will use the current top-most camera, this is the default value */
TOP;

/** The transition will create and use a new camera above all others */
NEW;

/** The transition will use the default cameras */
DEFAULT;
}

typedef TransitionTileData =
{
asset:FlxGraphicAsset,
Expand All @@ -28,44 +44,76 @@ typedef TransitionTileData =
*/
class TransitionData implements IFlxDestroyable
{
/** `NONE`, `TILE`, or `FADE` */
public var type:TransitionType;

/** The graphic to tile, when `TILE` type is used */
public var tileData:TransitionTileData;

/** The color of the transition */
public var color:FlxColor;

/** How long the transition will take */
public var duration:Float = 1.0;

/** Add a "wipe" effect to various transition styles */
public var direction:FlxPoint;

/** Used to override the options of the tween controlling this transtition */
public var tweenOptions:TweenOptions;

/** The area of the screen to display the transition */
public var region:FlxRect;


/**
* Whether this transition will use a new camera, the top camera, or the default camera
* @since 5.6.0
*/
public var cameraMode:TransitionCameraMode = TOP;

public function destroy():Void
{
tileData = null;
direction = null;
tweenOptions.onComplete = null;
tweenOptions.ease = null;
tweenOptions = null;
region = null;
direction = null;
}

public function new(TransType:TransitionType = FADE, Color:FlxColor = FlxColor.WHITE, Duration:Float = 1.0, ?Direction:FlxPoint,
?TileData:TransitionTileData, ?Region:FlxRect)

/**
* Used to define a transition for `FlxTransitionableState`
*
* @param type `NONE`, `TILE`, or `FADE`
* @param color The color of the transition
* @param duration How long the transition will take
* @param direction Add a "wipe" effect to various transition styles
* @param tileData The graphic to tile, when `TILE` type is used
* @param region The area of the screen to display the transition
* @param cameraMode Whether this transition will use a new camera, the top camera, or the default camera
*/
public function new(type = FADE, color = FlxColor.WHITE, duration = 1.0, ?direction:FlxPoint, ?tileData:TransitionTileData, ?region:FlxRect,
cameraMode = TOP)
{
type = TransType;
tileData = TileData;
duration = Duration;
color = Color;
direction = Direction;
this.type = type;
this.tileData = tileData;
this.duration = duration;
this.color = color;
if (direction == null)
{
direction = new FlxPoint(0, 0);
}
FlxMath.bound(direction.x, -1, 1);
FlxMath.bound(direction.y, -1, 1);
else
{
direction.x = FlxMath.bound(direction.x, -1, 1);
direction.y = FlxMath.bound(direction.y, -1, 1);
}
this.direction = direction;
tweenOptions = {onComplete: null};
region = Region;
if (Region == null)
if (region == null)
{
region = new FlxRect(0, 0, FlxG.width, FlxG.height);
}
this.region = region;
this.cameraMode = cameraMode;
}
}
51 changes: 39 additions & 12 deletions flixel/addons/transition/TransitionEffect.hx
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,79 @@ class TransitionEffect extends FlxSpriteGroup
{
public var finishCallback:Void->Void;
public var finished(default, null):Bool = false;

var _started:Bool = false;
var _endStatus:TransitionStatus;
var _finalDelayTime:Float = 0.0;

var _customCamera:FlxCamera;

var _data:TransitionData;

public function new(data:TransitionData)
{
_data = data;
super();
}

override public function destroy():Void
{
super.destroy();
finishCallback = null;

if (_customCamera != null)
{
// may already be removed via state switching
if (FlxG.cameras.list.contains(_customCamera))
FlxG.cameras.remove(_customCamera, true);

_customCamera = null;
}
}

public function start(NewStatus:TransitionStatus):Void
public function start(newStatus:TransitionStatus):Void
{
_started = true;

if (NewStatus == IN)
if (newStatus == IN)
{
_endStatus = FULL;
}
else
{
_endStatus = EMPTY;
}

switch (_data.cameraMode)
{
case NEW:
// create a new camera above everything else
_customCamera = new FlxCamera(0, 0, Std.int(_data.region.width), Std.int(_data.region.height));
_customCamera.bgColor = 0x0;
FlxG.cameras.add(_customCamera, false);
camera = _customCamera;
case TOP:
// get the last added camera so it shows up on top of everything
final cams = FlxG.cameras.list;
camera = cams[cams.length - 1];
case DEFAULT:
// do nothing
}
}

public function setStatus(NewStatus:TransitionStatus):Void
public function setStatus(newStatus:TransitionStatus):Void
{
// override per subclass
}

function delayThenFinish():Void
{
new FlxTimer().start(_finalDelayTime, onFinish); // force one last render call before exiting
}

function onFinish(f:FlxTimer):Void
{
finished = true;

if (finishCallback != null)
{
var callback = finishCallback;
Expand Down
3 changes: 3 additions & 0 deletions hxformat.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@
"doWhile": "next",
"tryBody": "next",
"tryCatch": "next"
},
"indentation":{
"trailingWhitespace": true
}
}

0 comments on commit 105f37a

Please sign in to comment.