Bugfixes. New additive zoom mode for camera tweening.

This commit is contained in:
Jenny Crowe 2024-03-16 08:38:10 -07:00
parent 1541f0aa68
commit 494a3c9e86
2 changed files with 66 additions and 20 deletions

View file

@ -255,14 +255,23 @@ class PlayState extends MusicBeatSubState
public var previousCameraFollowPoint:FlxPoint = null;
/**
* The current camera zoom level.
*
* The camera zoom is increased every beat, and lerped back to this value every frame, creating a smooth 'zoom-in' effect.
* Defaults to 1.05 but may be larger or smaller depending on the current stage,
* and may be changed by the `ZoomCamera` song event.
* The current camera zoom level without any modifiers applied.
*/
public var currentCameraZoom:Float = FlxCamera.defaultZoom * 1.05;
/**
* currentCameraZoom is increased every beat, and lerped back to this value every frame, creating a smooth 'zoom-in' effect.
* Defaults to 1.05, but may be larger or smaller depending on the current stage.
* Tweened via the `ZoomCamera` song event in direct mode.
*/
public var defaultCameraZoom:Float = FlxCamera.defaultZoom * 1.05;
/**
* Camera zoom applied on top of currentCameraZoom.
* Tweened via the `ZoomCamera` song event in additive mode.
*/
public var additiveCameraZoom:Float = 0;
/**
* The current HUD camera zoom level.
*
@ -959,7 +968,9 @@ class PlayState extends MusicBeatSubState
// Lerp the camera zoom towards the target level.
if (subState == null)
{
FlxG.camera.zoom = FlxMath.lerp(defaultCameraZoom, FlxG.camera.zoom, 0.95);
currentCameraZoom = FlxMath.lerp(defaultCameraZoom, currentCameraZoom, 0.95);
FlxG.camera.zoom = currentCameraZoom + additiveCameraZoom;
camHUD.zoom = FlxMath.lerp(defaultHUDCameraZoom, camHUD.zoom, 0.95);
}
@ -1349,7 +1360,7 @@ class PlayState extends MusicBeatSubState
if (FlxG.camera.zoom < (1.35 * defaultCameraZoom) && cameraZoomRate > 0 && Conductor.instance.currentBeat % cameraZoomRate == 0)
{
// Zoom camera in (1.5%)
FlxG.camera.zoom += cameraZoomIntensity * defaultCameraZoom;
currentCameraZoom += cameraZoomIntensity * defaultCameraZoom;
// Hud zooms double (3%)
camHUD.zoom += hudCameraZoomIntensity * defaultHUDCameraZoom;
}
@ -1541,6 +1552,11 @@ class PlayState extends MusicBeatSubState
{
// Apply camera zoom level from stage data.
defaultCameraZoom = currentStage.camZoom;
currentCameraZoom = defaultCameraZoom;
FlxG.camera.zoom = currentCameraZoom;
// Reset additive zoom.
additiveCameraZoom = 0;
}
/**
@ -3051,7 +3067,7 @@ class PlayState extends MusicBeatSubState
if (resetZoom)
{
FlxG.camera.zoom = defaultCameraZoom;
resetCameraZoom();
}
// Snap the camera to the follow point immediately.
@ -3097,24 +3113,40 @@ class PlayState extends MusicBeatSubState
}
/**
* Tweens the camera zoom to the desired amount. Tweens defaultCameraZoom to avoid breaking camera bops.
* Tweens the camera zoom to the desired amount.
*/
public function tweenCameraZoom(?zoom:Float, ?duration:Float, ?ease:Null<Float->Float>):Void
public function tweenCameraZoom(?zoom:Float, ?duration:Float, ?directMode:Bool, ?ease:Null<Float->Float>):Void
{
// Cancel the current tween if it's active.
cancelCameraZoomTween();
var targetZoom = zoom * FlxCamera.defaultZoom;
if (duration == 0)
if (directMode) // Direct mode: Tween defaultCameraZoom for basic "smooth" zooms.
{
// Instant zoom. No tween needed.
defaultCameraZoom = targetZoom;
if (duration == 0)
{
// Instant zoom. No tween needed.
defaultCameraZoom = targetZoom;
}
else
{
// Zoom tween! Caching it so we can cancel/pause it later if needed.
cameraZoomTween = FlxTween.tween(this, {defaultCameraZoom: targetZoom}, duration, {ease: ease});
}
}
else
else // Additive mode: Tween additiveCameraZoom for ease-based zooms.
{
// Zoom tween! Caching it so we can cancel/pause it later if needed.
cameraZoomTween = FlxTween.tween(this, {defaultCameraZoom: targetZoom}, duration, {ease: ease});
if (duration == 0)
{
// Instant zoom. No tween needed.
additiveCameraZoom = targetZoom;
}
else
{
// Zoom tween! Caching it so we can cancel/pause it later if needed.
cameraZoomTween = FlxTween.tween(this, {additiveCameraZoom: targetZoom}, duration, {ease: ease});
}
}
}

View file

@ -62,17 +62,23 @@ class ZoomCameraSongEvent extends SongEvent
var zoom:Null<Float> = data.getFloat('zoom');
if (zoom == null) zoom = 1.0;
var duration:Null<Float> = data.getFloat('duration');
if (duration == null) duration = 4.0;
var mode:Null<String> = data.getString('mode');
if (mode == null) mode = 'additive';
var ease:Null<String> = data.getString('ease');
if (ease == null) ease = 'linear';
var directMode:Bool = mode == 'direct';
// If it's a string, check the value.
switch (ease)
{
case 'INSTANT':
PlayState.instance.tweenCameraZoom(zoom, 0);
PlayState.instance.tweenCameraZoom(zoom, 0, directMode);
default:
var durSeconds = Conductor.instance.stepLengthMs * duration / 1000;
@ -83,7 +89,7 @@ class ZoomCameraSongEvent extends SongEvent
return;
}
PlayState.instance.tweenCameraZoom(zoom, durSeconds, easeFunction);
PlayState.instance.tweenCameraZoom(zoom, durSeconds, directMode, easeFunction);
}
}
@ -96,8 +102,9 @@ class ZoomCameraSongEvent extends SongEvent
* ```
* {
* 'zoom': FLOAT, // Target zoom level.
* 'duration': FLOAT, // Optional duration in steps
* 'ease': ENUM, // Optional easing function
* 'duration': FLOAT, // Optional duration in steps.
* 'mode': ENUM, // Whether to set additive zoom or direct zoom.
* 'ease': ENUM, // Optional easing function.
* }
* @return SongEventSchema
*/
@ -120,6 +127,13 @@ class ZoomCameraSongEvent extends SongEvent
type: SongEventFieldType.FLOAT,
units: 'steps'
},
{
name: 'mode',
title: 'Mode',
defaultValue: 'additive',
type: SongEventFieldType.ENUM,
keys: ['Additive' => 'additive', 'Direct' => 'direct']
},
{
name: 'ease',
title: 'Easing Type',