From ddb8e9da44940c13b73d849ff2e222773502f600 Mon Sep 17 00:00:00 2001 From: Vortex <73261680+Vortex2Oblivion@users.noreply.github.com> Date: Tue, 5 Nov 2024 14:44:40 -0500 Subject: [PATCH] fix some bugs --- source/states/PlayState.hx | 2 +- source/ui/FunkinSoundTray.hx | 19 ++- source/utilities/MathUtil.hx | 265 ++++++++++++++++++----------------- 3 files changed, 150 insertions(+), 136 deletions(-) diff --git a/source/states/PlayState.hx b/source/states/PlayState.hx index fb2df81870..acbd3bdf88 100644 --- a/source/states/PlayState.hx +++ b/source/states/PlayState.hx @@ -976,7 +976,7 @@ class PlayState extends MusicBeatState { #if (MODCHARTING_TOOLS) if (SONG.modchartingTools || Assets.exists(Paths.json("song data/" + SONG.song.toLowerCase() + "/modchart")) - || Assets.exists(Paths.json("song data/" + SONG.song.toLowerCase() + "/modchart" + storyDifficultyStr.toLowerCase()))) { + || Assets.exists(Paths.json("song data/" + SONG.song.toLowerCase() + "/modchart-" + storyDifficultyStr.toLowerCase()))) { playfieldRenderer = new PlayfieldRenderer(strumLineNotes, notes, this); playfieldRenderer.cameras = [camHUD]; add(playfieldRenderer); diff --git a/source/ui/FunkinSoundTray.hx b/source/ui/FunkinSoundTray.hx index 3b4dbb4fc2..6637c22741 100644 --- a/source/ui/FunkinSoundTray.hx +++ b/source/ui/FunkinSoundTray.hx @@ -1,14 +1,12 @@ package ui; +import openfl.utils.Assets; +import utilities.MathUtil; import flixel.FlxG; +import openfl.display.Bitmap; import flixel.system.ui.FlxSoundTray; import flixel.tweens.FlxTween; -import flixel.system.FlxAssets; -import flixel.tweens.FlxEase; -import openfl.display.Bitmap; import openfl.display.BitmapData; -import openfl.utils.Assets; -import utilities.MathUtil; /** * Extends the default flixel soundtray, but with some art @@ -72,17 +70,18 @@ class FunkinSoundTray extends FlxSoundTray { volumeUpSound = Paths.sound("soundtray/Volup"); volumeDownSound = Paths.sound("soundtray/Voldown"); volumeMaxSound = Paths.sound("soundtray/VolMAX"); - - // trace("Custom tray added!"); } override public function update(MS:Float):Void { y = MathUtil.coolLerp(y, lerpYPos, 0.1); alpha = MathUtil.coolLerp(alpha, alphaTarget, 0.25); + var shouldHide = (FlxG.sound.muted == false && FlxG.sound.volume > 0); + // Animate sound tray thing if (_timer > 0) { - _timer -= (MS / 1000); + if (shouldHide) + _timer -= (MS / 1000); alphaTarget = 1; } else if (y >= -height) { lerpYPos = -height - 10; @@ -114,9 +113,9 @@ class FunkinSoundTray extends FlxSoundTray { lerpYPos = 10; visible = true; active = true; - var globalVolume:Int = Math.round(FlxG.sound.volume * 10); + var globalVolume:Int = Math.round(MathUtil.logToLinear(FlxG.sound.volume) * 10); - if (FlxG.sound.muted) { + if (FlxG.sound.muted || FlxG.sound.volume == 0) { globalVolume = 0; } diff --git a/source/utilities/MathUtil.hx b/source/utilities/MathUtil.hx index fbcba07b79..860b378a0a 100644 --- a/source/utilities/MathUtil.hx +++ b/source/utilities/MathUtil.hx @@ -5,129 +5,144 @@ import flixel.FlxG; /** * Utilities for performing mathematical operations. */ -class MathUtil -{ - /** - * Euler's constant and the base of the natural logarithm. - * Math.E is not a constant in Haxe, so we'll just define it ourselves. - */ - public static final E:Float = 2.71828182845904523536; - - /** - * Perform linear interpolation between the base and the target, based on the current framerate. - * @param base The starting value, when `progress <= 0`. - * @param target The ending value, when `progress >= 1`. - * @param ratio Value used to interpolate between `base` and `target`. - * - * @return The interpolated value. - */ - @:deprecated('Use smoothLerp instead') - public static inline function coolLerp(base:Float, target:Float, ratio:Float):Float - { - return base + cameraLerp(ratio) * (target - base); - } - - /** - * Perform linear interpolation based on the current framerate. - * @param lerp Value used to interpolate between `base` and `target`. - * - * @return The interpolated value. - */ - @:deprecated('Use smoothLerp instead') - public static inline function cameraLerp(lerp:Float):Float - { - return lerp * (FlxG.elapsed / (1 / 60)); - } - - /** - * Get the logarithm of a value with a given base. - * @param base The base of the logarithm. - * @param value The value to get the logarithm of. - * @return `log_base(value)` - */ - public static inline function logBase(base:Float, value:Float):Float - { - return Math.log(value) / Math.log(base); - } - - public static function easeInOutCirc(x:Float):Float - { - if (x <= 0.0) return 0.0; - if (x >= 1.0) return 1.0; - var result:Float = (x < 0.5) ? (1 - Math.sqrt(1 - 4 * x * x)) / 2 : (Math.sqrt(1 - 4 * (1 - x) * (1 - x)) + 1) / 2; - return (result == Math.NaN) ? 1.0 : result; - } - - public static function easeInOutBack(x:Float, ?c:Float = 1.70158):Float - { - if (x <= 0.0) return 0.0; - if (x >= 1.0) return 1.0; - var result:Float = (x < 0.5) ? (2 * x * x * ((c + 1) * 2 * x - c)) / 2 : (1 - 2 * (1 - x) * (1 - x) * ((c + 1) * 2 * (1 - x) - c)) / 2; - return (result == Math.NaN) ? 1.0 : result; - } - - public static function easeInBack(x:Float, ?c:Float = 1.70158):Float - { - if (x <= 0.0) return 0.0; - if (x >= 1.0) return 1.0; - return (1 + c) * x * x * x - c * x * x; - } - - public static function easeOutBack(x:Float, ?c:Float = 1.70158):Float - { - if (x <= 0.0) return 0.0; - if (x >= 1.0) return 1.0; - return 1 + (c + 1) * Math.pow(x - 1, 3) + c * Math.pow(x - 1, 2); - } - - /** - * Get the base-2 logarithm of a value. - * @param x value - * @return `2^x` - */ - public static inline function exp2(x:Float):Float - { - return Math.pow(2, x); - } - - /** - * Linearly interpolate between two values. - * - * @param base The starting value, when `progress <= 0`. - * @param target The ending value, when `progress >= 1`. - * @param progress Value used to interpolate between `base` and `target`. - * @return The interpolated value. - */ - public static inline function lerp(base:Float, target:Float, progress:Float):Float - { - return base + progress * (target - base); - } - - /** - * Perform a framerate-independent linear interpolation between the base value and the target. - * @param current The current value. - * @param target The target value. - * @param elapsed The time elapsed since the last frame. - * @param duration The total duration of the interpolation. Nominal duration until remaining distance is less than `precision`. - * @param precision The target precision of the interpolation. Defaults to 1% of distance remaining. - * @see https://twitter.com/FreyaHolmer/status/1757918211679650262 - * - * @return A value between the current value and the target value. - */ - public static function smoothLerp(current:Float, target:Float, elapsed:Float, duration:Float, precision:Float = 1 / 100):Float - { - // An alternative algorithm which uses a separate half-life value: - // var halfLife:Float = -duration / logBase(2, precision); - // lerp(current, target, 1 - exp2(-elapsed / halfLife)); - - if (current == target) return target; - - var result:Float = lerp(current, target, 1 - Math.pow(precision, elapsed / duration)); - - // TODO: Is there a better way to ensure a lerp which actually reaches the target? - // Research a framerate-independent PID lerp. - if (Math.abs(result - target) < (precision * target)) result = target; - - return result; - } +class MathUtil { + /** + * Euler's constant and the base of the natural logarithm. + * Math.E is not a constant in Haxe, so we'll just define it ourselves. + */ + public static final E:Float = 2.71828182845904523536; + + /** + * Perform linear interpolation between the base and the target, based on the current framerate. + * @param base The starting value, when `progress <= 0`. + * @param target The ending value, when `progress >= 1`. + * @param ratio Value used to interpolate between `base` and `target`. + * + * @return The interpolated value. + */ + @:deprecated('Use smoothLerp instead') + public static inline function coolLerp(base:Float, target:Float, ratio:Float):Float { + return base + cameraLerp(ratio) * (target - base); + } + + /** + * Perform linear interpolation based on the current framerate. + * @param lerp Value used to interpolate between `base` and `target`. + * + * @return The interpolated value. + */ + @:deprecated('Use smoothLerp instead') + public static inline function cameraLerp(lerp:Float):Float { + return lerp * (FlxG.elapsed / (1 / 60)); + } + + /** + * Get the logarithm of a value with a given base. + * @param base The base of the logarithm. + * @param value The value to get the logarithm of. + * @return `log_base(value)` + */ + public static inline function logBase(base:Float, value:Float):Float { + return Math.log(value) / Math.log(base); + } + + public static function easeInOutCirc(x:Float):Float { + if (x <= 0.0) + return 0.0; + if (x >= 1.0) + return 1.0; + var result:Float = (x < 0.5) ? (1 - Math.sqrt(1 - 4 * x * x)) / 2 : (Math.sqrt(1 - 4 * (1 - x) * (1 - x)) + 1) / 2; + return (result == Math.NaN) ? 1.0 : result; + } + + public static function easeInOutBack(x:Float, ?c:Float = 1.70158):Float { + if (x <= 0.0) + return 0.0; + if (x >= 1.0) + return 1.0; + var result:Float = (x < 0.5) ? (2 * x * x * ((c + 1) * 2 * x - c)) / 2 : (1 - 2 * (1 - x) * (1 - x) * ((c + 1) * 2 * (1 - x) - c)) / 2; + return (result == Math.NaN) ? 1.0 : result; + } + + public static function easeInBack(x:Float, ?c:Float = 1.70158):Float { + if (x <= 0.0) + return 0.0; + if (x >= 1.0) + return 1.0; + return (1 + c) * x * x * x - c * x * x; + } + + public static function easeOutBack(x:Float, ?c:Float = 1.70158):Float { + if (x <= 0.0) + return 0.0; + if (x >= 1.0) + return 1.0; + return 1 + (c + 1) * Math.pow(x - 1, 3) + c * Math.pow(x - 1, 2); + } + + /** + * Get the base-2 logarithm of a value. + * @param x value + * @return `2^x` + */ + public static inline function exp2(x:Float):Float { + return Math.pow(2, x); + } + + /** + * Linearly interpolate between two values. + * + * @param base The starting value, when `progress <= 0`. + * @param target The ending value, when `progress >= 1`. + * @param progress Value used to interpolate between `base` and `target`. + * @return The interpolated value. + */ + public static inline function lerp(base:Float, target:Float, progress:Float):Float { + return base + progress * (target - base); + } + + /** + * Perform a framerate-independent linear interpolation between the base value and the target. + * @param current The current value. + * @param target The target value. + * @param elapsed The time elapsed since the last frame. + * @param duration The total duration of the interpolation. Nominal duration until remaining distance is less than `precision`. + * @param precision The target precision of the interpolation. Defaults to 1% of distance remaining. + * @see https://twitter.com/FreyaHolmer/status/1757918211679650262 + * + * @return A value between the current value and the target value. + */ + public static function smoothLerp(current:Float, target:Float, elapsed:Float, duration:Float, precision:Float = 1 / 100):Float { + // An alternative algorithm which uses a separate half-life value: + // var halfLife:Float = -duration / logBase(2, precision); + // lerp(current, target, 1 - exp2(-elapsed / halfLife)); + + if (current == target) + return target; + + var result:Float = lerp(current, target, 1 - Math.pow(precision, elapsed / duration)); + + // TODO: Is there a better way to ensure a lerp which actually reaches the target? + // Research a framerate-independent PID lerp. + if (Math.abs(result - target) < (precision * target)) + result = target; + + return result; + } + + public static function linearToLog(x:Float, minValue:Float = 0.001):Float { + // Ensure x is between 0 and 1 + x = Math.max(0, Math.min(1, x)); + + // Convert linear scale to logarithmic + return Math.exp(Math.log(minValue) * (1 - x)); + } + + public static function logToLinear(x:Float, minValue:Float = 0.001):Float { + // Ensure x is between minValue and 1 + x = Math.max(minValue, Math.min(1, x)); + + // Convert logarithmic scale to linear + return 1 - (Math.log(x) / Math.log(minValue)); + } }