Skip to content

Commit

Permalink
fix some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
Vortex2Oblivion committed Nov 5, 2024
1 parent d4c7080 commit ddb8e9d
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 136 deletions.
2 changes: 1 addition & 1 deletion source/states/PlayState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
19 changes: 9 additions & 10 deletions source/ui/FunkinSoundTray.hx
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
265 changes: 140 additions & 125 deletions source/utilities/MathUtil.hx
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

0 comments on commit ddb8e9d

Please sign in to comment.