diff --git a/source/funkin/play/GameOverSubState.hx b/source/funkin/play/GameOverSubState.hx index 21cde787e..74bed5707 100644 --- a/source/funkin/play/GameOverSubState.hx +++ b/source/funkin/play/GameOverSubState.hx @@ -7,6 +7,7 @@ import flixel.FlxObject; import flixel.FlxSprite; import flixel.util.FlxColor; import flixel.util.FlxTimer; +import funkin.util.HapticUtil; import funkin.audio.FunkinSound; import funkin.graphics.FunkinSprite; import funkin.modding.events.ScriptEvent; @@ -19,7 +20,6 @@ import funkin.util.MathUtil; import funkin.effects.RetroCameraFade; import flixel.math.FlxPoint; import funkin.mobile.util.TouchUtil; -import funkin.mobile.util.HapticUtil; import openfl.utils.Assets; /** diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 9d9420b92..ac8f50633 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -54,10 +54,10 @@ import funkin.ui.mainmenu.MainMenuState; import funkin.ui.MusicBeatSubState; import funkin.ui.transition.LoadingState; import funkin.util.SerializerUtil; +import funkin.util.HapticUtil; import haxe.Int64; #if mobile import funkin.mobile.util.TouchUtil; -import funkin.mobile.util.HapticUtil; import funkin.mobile.ui.FunkinHitbox; import funkin.mobile.ui.FunkinHitbox.FunkinHitboxControlSchemes; #if NO_DISABLE_ADMOB_ADS diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 43229493f..7d87dee46 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -24,6 +24,7 @@ import flixel.tweens.FlxTween; import flixel.addons.display.FlxBackdrop; import funkin.audio.FunkinSound; import flixel.util.FlxGradient; +import funkin.util.HapticUtil; import flixel.util.FlxTimer; import funkin.play.scoring.Scoring; import funkin.save.Save.SaveScoreData; @@ -35,7 +36,6 @@ import funkin.api.newgrounds.Medals; #end #if mobile import funkin.mobile.util.TouchUtil; -import funkin.mobile.util.HapticUtil; #if NO_DISABLE_ADMOB_ADS import funkin.mobile.util.AdMobUtil; #end @@ -515,12 +515,14 @@ class ResultState extends MusicBeatSubState FunkinSound.playOnce(Paths.sound('scrollMenu')); #if HAPTIC_VIBRATIONS + // Weak vibration each number increase. HapticUtil.vibrate(0, 10); #end } }, onComplete: _ -> { #if HAPTIC_VIBRATIONS + // Strong vibration when rank number tween ends. HapticUtil.vibrate(0, Constants.DEFAULT_VIBRATION_DURATION, Constants.MAX_VIBRATION_AMPLITUDE); #end @@ -728,83 +730,100 @@ class ResultState extends MusicBeatSubState #if HAPTIC_VIBRATIONS private function handleAnimationVibrations() { - switch (rank) + for (atlas in characterAtlasAnimations) { - case ScoringRank.PERFECT | ScoringRank.PERFECT_GOLD: - for (atlas in characterAtlasAnimations) - { - @:nullSafety(Off) + if (atlas == null || atlas.sprite == null) continue; + + switch (rank) + { + case ScoringRank.PERFECT | ScoringRank.PERFECT_GOLD: switch (playerCharacterId) { // Feel the bed fun :freaky: case "bf": - if (atlas.sprite.anim.curFrame > 87 && atlas.sprite.anim.curFrame % 5 == 0) HapticUtil.vibrate(0, 10, Constants.MAX_VIBRATION_AMPLITUDE); + if (atlas.sprite.anim.curFrame > 87 && atlas.sprite.anim.curFrame % 5 == 0) + { + HapticUtil.vibrate(0, 10, Constants.MAX_VIBRATION_AMPLITUDE); + break; + } // GF slams into the wall. - if (atlas.sprite.anim.curFrame == 51) HapticUtil.vibrate(0, 10, Std.int(Constants.MAX_VIBRATION_AMPLITUDE / 3)); + if (atlas.sprite.anim.curFrame == 51) + { + HapticUtil.vibrate(0, 10, Math.floor(Constants.MAX_VIBRATION_AMPLITUDE / 3)); + break; + } // Pico drop-kicking Nene. case "pico": - if (atlas.sprite.anim.curFrame == 52) HapticUtil.vibrate(Constants.DEFAULT_VIBRATION_PERIOD, Constants.DEFAULT_VIBRATION_DURATION * 5, - Constants.MAX_VIBRATION_AMPLITUDE); + if (atlas.sprite.anim.curFrame == 52) + { + HapticUtil.vibrate(Constants.DEFAULT_VIBRATION_PERIOD, Constants.DEFAULT_VIBRATION_DURATION * 5, Constants.MAX_VIBRATION_AMPLITUDE); + break; + } default: - // nothing. + break; } - } - case ScoringRank.GREAT | ScoringRank.EXCELLENT: - for (atlas in characterAtlasAnimations) - { + case ScoringRank.GREAT | ScoringRank.EXCELLENT: switch (playerCharacterId) { // Pico explodes the targets with a rocket launcher. case "pico": - if (atlas.sprite.anim.curFrame == 45) HapticUtil.vibrate(0, 10, Std.int(Constants.MAX_VIBRATION_AMPLITUDE / 3)); + // Pico shoots. + if (atlas.sprite.anim.curFrame == 45) + { + HapticUtil.vibrate(0, 10, Math.floor(Constants.MAX_VIBRATION_AMPLITUDE / 3)); + break; + } - if (atlas.sprite.anim.curFrame == 50) HapticUtil.vibrate(Constants.DEFAULT_VIBRATION_PERIOD, Constants.DEFAULT_VIBRATION_DURATION, - Constants.MAX_VIBRATION_AMPLITUDE); + // The targets explode. + if (atlas.sprite.anim.curFrame == 50) + { + HapticUtil.vibrate(Constants.DEFAULT_VIBRATION_PERIOD, Constants.DEFAULT_VIBRATION_DURATION, Constants.MAX_VIBRATION_AMPLITUDE); + break; + } default: - // nothing. + break; } - } - case ScoringRank.GOOD: - for (atlas in characterAtlasAnimations) - { + case ScoringRank.GOOD: switch (playerCharacterId) { // Pico shooting the targets. case "pico": - final frames:Null>> = [[40, 50], [80, 90], [140, 157]]; + if (atlas.sprite.anim.curFrame % 2 != 0) continue; + final frames:Array> = [[40, 50], [80, 90], [140, 157]]; for (i in 0...frames.length) { - if (atlas.sprite.anim.curFrame >= frames[i][0] - && atlas.sprite.anim.curFrame <= frames[i][1] - && atlas.sprite.anim.curFrame % 2 == 0) HapticUtil.vibrate(0, 10, Constants.MAX_VIBRATION_AMPLITUDE); + if (atlas.sprite.anim.curFrame < frames[i][0] || atlas.sprite.anim.curFrame > frames[i][1]) continue; + + HapticUtil.vibrate(0, 10, Constants.MAX_VIBRATION_AMPLITUDE); + break; } default: - // nothing. + break; } - } - case ScoringRank.SHIT: - for (atlas in characterAtlasAnimations) - { + case ScoringRank.SHIT: switch (playerCharacterId) { // BF falling and GF slams on BF with her ass. case "bf": - if (atlas.sprite.anim.curFrame == 5 || atlas.sprite.anim.curFrame == 90) HapticUtil.vibrate(Constants.DEFAULT_VIBRATION_PERIOD * 2, - Constants.DEFAULT_VIBRATION_DURATION * 2, Constants.MAX_VIBRATION_AMPLITUDE); + if (atlas.sprite.anim.curFrame == 5 || atlas.sprite.anim.curFrame == 90) + { + HapticUtil.vibrate(Constants.DEFAULT_VIBRATION_PERIOD * 2, Constants.DEFAULT_VIBRATION_DURATION * 2, Constants.MAX_VIBRATION_AMPLITUDE); + break; + } default: - // nothing. + break; } - } + } } } #end diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 3486dde02..3bce3db48 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -42,14 +42,15 @@ import funkin.ui.transition.LoadingState; import funkin.ui.transition.StickerSubState; import funkin.util.MathUtil; import funkin.util.SortUtil; +import funkin.util.HapticUtil; import openfl.display.BlendMode; import funkin.data.freeplay.style.FreeplayStyleRegistry; #if FEATURE_DISCORD_RPC import funkin.api.discord.DiscordClient; #end +#if TOUCH_CONTROLS import funkin.mobile.util.TouchUtil; import funkin.mobile.util.SwipeUtil; -import funkin.mobile.util.HapticUtil; #end import flixel.system.scaleModes.FullScreenScaleMode; diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index 0acc47672..c1224d270 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -9,6 +9,7 @@ import flixel.tweens.FlxTween; import flixel.util.FlxColor; import flixel.util.FlxDirectionFlags; import flixel.util.FlxTimer; +import funkin.util.HapticUtil; import flixel.util.typeLimit.NextState; import funkin.audio.visualize.SpectogramSprite; import funkin.graphics.shaders.ColorSwap; @@ -35,7 +36,6 @@ import funkin.save.Save; #if mobile import funkin.mobile.util.TouchUtil; import funkin.mobile.util.SwipeUtil; -import funkin.mobile.util.HapticUtil; #end #if desktop diff --git a/source/funkin/mobile/util/HapticUtil.hx b/source/funkin/util/HapticUtil.hx similarity index 51% rename from source/funkin/mobile/util/HapticUtil.hx rename to source/funkin/util/HapticUtil.hx index 77f9de878..18e3bf11c 100644 --- a/source/funkin/mobile/util/HapticUtil.hx +++ b/source/funkin/util/HapticUtil.hx @@ -1,4 +1,4 @@ -package funkin.mobile.util; +package funkin.util; import lime.ui.Haptic; import flixel.tweens.FlxTween; @@ -6,13 +6,12 @@ import flixel.tweens.FlxTween; /** * Utility class for extra vibration functions. */ -@:nullSafety class HapticUtil { /** * Tween that is used in increasingVibrate function for tweening vibration amplitude. */ - public static var amplitudeTween:Null; + public static var amplitudeTween:FlxTween; /** * Triggers vibration. @@ -20,39 +19,39 @@ class HapticUtil * @param duration The time taken for a complete cycle. * @param amplitude The distance of movement of the wave from its original position. */ - public static function vibrate(period:Int = Constants.DEFAULT_VIBRATION_PERIOD, duration:Int = Constants.DEFAULT_VIBRATION_DURATION, amplitude:Int = 0):Void + public static inline function vibrate(period:Int = Constants.DEFAULT_VIBRATION_PERIOD, duration:Int = Constants.DEFAULT_VIBRATION_DURATION, + amplitude:Int = 0):Void { #if HAPTIC_VIBRATIONS if (!Preferences.vibration) return; Haptic.vibrate(period, duration, amplitude); #end - - return; } /** * Triggers a queue of small vibrations with increasing amplitude. * When the amplitudeTween is finished, triggers a single strong vibration. - * @param fromValue Start amplitude value. - * @param toValue End amplitude value. - * @param duration Duration of the tween. + * @param startAmplitude Start amplitude value. + * @param targetAmplitude Target amplitude value. + * @param tweenDuration Duration of the tween. */ - public static function increasingVibrate(fromValue:Float, toValue:Float, duration:Float = 1):Void + public static function increasingVibrate(startAmplitude:Float, targetAmplitude:Float, tweenDuration:Float = 1):Void { #if HAPTIC_VIBRATIONS if (!Preferences.vibration) return; - amplitudeTween = FlxTween.num(fromValue, toValue, duration, + if (amplitudeTween != null) amplitudeTween.cancel(); + + amplitudeTween = FlxTween.num(startAmplitude, targetAmplitude, tweenDuration, { onComplete: function(_) { - vibrate(Constants.DEFAULT_VIBRATION_PERIOD, Constants.DEFAULT_VIBRATION_DURATION, Std.int(toValue * 2)); + final lastAmplitude:Int = Math.floor(targetAmplitude * 2); + vibrate(Constants.DEFAULT_VIBRATION_PERIOD, Constants.DEFAULT_VIBRATION_DURATION, lastAmplitude); } - }, function(num) { - vibrate(0, Std.int(Constants.DEFAULT_VIBRATION_DURATION / 10), Std.int(num)); + }, function(currentAmplitude:Float) { + vibrate(0, Math.floor(Constants.DEFAULT_VIBRATION_DURATION / 10), Math.floor(currentAmplitude)); }); #end - - return; } }