From f9aff5b11bb37de5700a0c07f91ac49c9764f24c Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 17:49:27 +0100 Subject: [PATCH 01/17] upgrade sparkles.. --- source/funkin/ui/mainmenu/UpgradeSparkle.hx | 76 +++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 source/funkin/ui/mainmenu/UpgradeSparkle.hx diff --git a/source/funkin/ui/mainmenu/UpgradeSparkle.hx b/source/funkin/ui/mainmenu/UpgradeSparkle.hx new file mode 100644 index 000000000..4abd6557e --- /dev/null +++ b/source/funkin/ui/mainmenu/UpgradeSparkle.hx @@ -0,0 +1,76 @@ +package funkin.ui.mainmenu; + +import flixel.FlxSprite; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.util.FlxTimer; +import flixel.math.FlxRect; + +class UpgradeSparkle extends FlxSprite +{ + var sparkleTimer:FlxTimer; + + public var bounds:FlxRect; + + public function new(_x:Float, _y:Float, _width:Float, _height:Float, big:Bool) + { + super(0, 0); + bounds = FlxRect.get(_x, _y, _width, _height); + if (big) + { + loadGraphic(Paths.image('mainmenu/upgradeshine_big')); + } + else + { + loadGraphic(Paths.image('mainmenu/upgradeshine_small')); + } + sparkleTimer = new FlxTimer().start(FlxG.random.float(2, 7), sparkleEffect); + visible = false; + } + + public function cancelSparkle():Void + { + if (sparkleTimer != null) sparkleTimer.cancel(); + FlxTween.cancelTweensOf(this); + alpha = 0; + } + + public function restartSparkle():Void + { + if (sparkleTimer != null) sparkleTimer.cancel(); + FlxTween.cancelTweensOf(this); + alpha = 1; + sparkleTimer = new FlxTimer().start(FlxG.random.float(2, 7), sparkleEffect); + } + + function sparkleEffect(timer:FlxTimer):Void + { + visible = true; + alpha = 1; + + trace('sparkle!', x, y); + + flipX = !flipX; + + var targetScale:Float = FlxG.random.float(0.6, 1); + scale.set(targetScale, targetScale); + updateHitbox(); + + setPosition(FlxG.random.float(bounds.x, bounds.x + bounds.width), FlxG.random.float(bounds.y, bounds.y + bounds.height)); + x -= width / 2; + y -= height / 2; + + angle += 70; + + var targetVelocity:Float = FlxG.random.float(120, 300); + if (FlxG.random.bool(50)) targetVelocity = targetVelocity * -1; + angularVelocity = targetVelocity; + angularDrag = 200; + + var targetTime:Float = FlxG.random.float(0.3, 0.8); + FlxTween.tween(this.scale, {x: targetScale * 0.001, y: targetScale * 0.001}, targetTime, {ease: FlxEase.backIn}); + FlxTween.tween(this, {alpha: 0}, targetTime, {ease: FlxEase.quintIn}); + + sparkleTimer = new FlxTimer().start(FlxG.random.float(2, 7), sparkleEffect); + } +} From db2644c0ff3aebeb1c4f79011142862cbaa52f62 Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 17:49:37 +0100 Subject: [PATCH 02/17] add upgrade button to main menu + simple logic --- source/funkin/ui/mainmenu/MainMenuState.hx | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index 58ff85d97..e6cbe2947 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -25,6 +25,8 @@ import funkin.ui.Prompt; import funkin.util.WindowUtil; import funkin.util.TouchUtil; import funkin.api.newgrounds.Referral; +import funkin.ui.mainmenu.UpgradeSparkle; +import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; #if FEATURE_DISCORD_RPC import funkin.api.discord.DiscordClient; #end @@ -43,6 +45,11 @@ class MainMenuState extends MusicBeatState static var rememberedSelectedIndex:Int = 0; + // TODO: this needs to eventually reflect the actual state of whether the player has upgraded or not. + // this should never be false on non-mobile targets. + var hasUpgraded:Bool = true; + var upgradeSparkles:FlxTypedSpriteGroup; + public function new(?_overrideMusic:Bool = false) { super(); @@ -123,6 +130,14 @@ class MainMenuState extends MusicBeatState var targetCharacter:Null = null; #end + if (!hasUpgraded) + { + for (i in 0...upgradeSparkles.length) + { + upgradeSparkles.members[i].cancelSparkle(); + } + } + openSubState(new FreeplayState( { character: targetCharacter @@ -143,6 +158,17 @@ class MainMenuState extends MusicBeatState startExitState(() -> new funkin.ui.options.OptionsState()); }); + if (!hasUpgraded) + { + upgradeSparkles = new FlxTypedSpriteGroup(); + add(upgradeSparkles); + + createMenuItem('upgrade', 'mainmenu/upgrade', function() { + // TODO: this needs to actually lead you to the purchase screen + startExitState(() -> new funkin.ui.options.OptionsState()); + }); + } + createMenuItem('credits', 'mainmenu/credits', function() { startExitState(() -> new funkin.ui.credits.CreditsState()); }); @@ -167,6 +193,28 @@ class MainMenuState extends MusicBeatState menuItems.selectItem(rememberedSelectedIndex); + if (!hasUpgraded) + { + // the upgrade item + var targetItem = menuItems.members[4]; + for (i in 0...8) + { + var sparkle:UpgradeSparkle = new UpgradeSparkle(targetItem.x - (targetItem.width / 2), targetItem.y - (targetItem.height / 2), targetItem.width, + targetItem.height, FlxG.random.bool(80)); + upgradeSparkles.add(sparkle); + + sparkle.scrollFactor.x = 0.0; + sparkle.scrollFactor.y = 0.4; + } + + subStateClosed.add(_ -> { + for (i in 0...upgradeSparkles.length) + { + upgradeSparkles.members[i].restartSparkle(); + } + }); + } + resetCamStuff(); // reset camera when debug menu is closed From 4746e8d7a5f852b93865e4559c3baeecb277036c Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 17:50:16 +0100 Subject: [PATCH 03/17] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index d861ebac0..aa426c217 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d861ebac027dd07d0254c79d7c89b59ee04b38f1 +Subproject commit aa426c217aa5236ef14e7fb55f5bf99a09d56d58 From 38e0cb6ab1df3766e1dcd41229b74aaea02a714f Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 21:19:11 +0100 Subject: [PATCH 04/17] remove trace from sparkles --- source/funkin/ui/mainmenu/UpgradeSparkle.hx | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/funkin/ui/mainmenu/UpgradeSparkle.hx b/source/funkin/ui/mainmenu/UpgradeSparkle.hx index 4abd6557e..0a9a9baa0 100644 --- a/source/funkin/ui/mainmenu/UpgradeSparkle.hx +++ b/source/funkin/ui/mainmenu/UpgradeSparkle.hx @@ -48,8 +48,6 @@ class UpgradeSparkle extends FlxSprite visible = true; alpha = 1; - trace('sparkle!', x, y); - flipX = !flipX; var targetScale:Float = FlxG.random.float(0.6, 1); From e457b3e03b4a222817356127c0acbd0101cc604c Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 21:19:36 +0100 Subject: [PATCH 05/17] add instant option for back button --- source/funkin/mobile/ui/FunkinBackButton.hx | 28 +++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/source/funkin/mobile/ui/FunkinBackButton.hx b/source/funkin/mobile/ui/FunkinBackButton.hx index 957be9cce..01ebf2d7f 100644 --- a/source/funkin/mobile/ui/FunkinBackButton.hx +++ b/source/funkin/mobile/ui/FunkinBackButton.hx @@ -5,11 +5,16 @@ import flixel.util.FlxColor; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import funkin.util.HapticUtil; +import flixel.util.FlxSignal; class FunkinBackButton extends FunkinButton { var restingOpacity:Float; + public var onConfirmEnd(default, null):FlxSignal = new FlxSignal(); + + var instant:Bool = false; + /** * Creates a new FunkinBackButton instance. * @@ -17,8 +22,11 @@ class FunkinBackButton extends FunkinButton * @param yPos The y position of the object. * @param theColor Button's optional color. * @param confirmCallback An optional callback function that will be triggered when the object is clicked. + * @param restOpacity An optional float that is the alpha the button will be when not selected/hovered over. + * @param instant An optional flag that makes the button not play the full animation before calling the callback. */ - public function new(?xPos:Float = 0, ?yPos:Float = 0, ?theColor:FlxColor = FlxColor.WHITE, ?confirmCallback:Void->Void, ?_restOpacity:Float = 0.3):Void + public function new(?xPos:Float = 0, ?yPos:Float = 0, ?theColor:FlxColor = FlxColor.WHITE, ?confirmCallback:Void->Void, ?_restOpacity:Float = 0.3, + _instant:Bool = false):Void { super(xPos, yPos); @@ -36,9 +44,18 @@ class FunkinBackButton extends FunkinButton alpha = restingOpacity; ignoreDownHandler = true; + instant = _instant; + + if (instant) + { + onUp.add(confirmCallback); + } + else + { + onConfirmEnd.add(confirmCallback); + } onUp.add(playConfirmAnim); - if (confirmCallback != null) onUp.add(confirmCallback); onDown.add(playHoldAnim); onOut.add(playOutAnim); } @@ -60,6 +77,13 @@ class FunkinBackButton extends FunkinButton HapticUtil.vibrate(0, 0.05, 0.5); animation.play('confirm'); + if (!instant) + { + animation.onFinish.add(function(name:String) { + onConfirmEnd.dispatch(); + }); + } + onUp.remove(playConfirmAnim); onDown.remove(playHoldAnim); onOut.remove(playOutAnim); From 250b5cb54ff3db5e7fd9db2d348e8b095a761041 Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 21:19:48 +0100 Subject: [PATCH 06/17] add options button --- .../mobile/ui/mainmenu/FunkinOptionsButton.hx | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 source/funkin/mobile/ui/mainmenu/FunkinOptionsButton.hx diff --git a/source/funkin/mobile/ui/mainmenu/FunkinOptionsButton.hx b/source/funkin/mobile/ui/mainmenu/FunkinOptionsButton.hx new file mode 100644 index 000000000..12e68004e --- /dev/null +++ b/source/funkin/mobile/ui/mainmenu/FunkinOptionsButton.hx @@ -0,0 +1,103 @@ +package funkin.mobile.ui.mainmenu; + +import flixel.FlxG; +import flixel.util.FlxColor; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import funkin.util.HapticUtil; +import flixel.util.FlxSignal; +import flixel.util.FlxTimer; +import funkin.audio.FunkinSound; + +class FunkinOptionsButton extends FunkinButton +{ + public var onConfirmEnd(default, null):FlxSignal = new FlxSignal(); + + var instant:Bool = false; + + /** + * Creates a new FunkinOptionsButton instance. + * + * @param xPos The x position of the object. + * @param yPos The y position of the object. + * @param confirmCallback An optional callback function that will be triggered when the object is clicked. + * @param instant An optional flag that makes the button not play the full animation before calling the callback. + */ + public function new(?xPos:Float = 0, ?yPos:Float = 0, ?confirmCallback:Void->Void, _instant:Bool = false):Void + { + super(xPos, yPos); + + frames = Paths.getSparrowAtlas("mainmenu/optionsButton"); + animation.addByIndices('idle', 'options', [0], "", 24, false); + animation.addByIndices('hold', 'options', [3], "", 24, false); + animation.addByIndices('confirm', 'options', [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], "", 24, false); + animation.play("idle"); + + scale.set(0.7, 0.7); + updateHitbox(); + + ignoreDownHandler = true; + instant = _instant; + + if (instant) + { + onUp.add(confirmCallback); + } + else + { + onConfirmEnd.add(confirmCallback); + } + + onUp.add(playConfirmAnim); + onDown.add(playHoldAnim); + onOut.add(playOutAnim); + } + + function playHoldAnim():Void + { + FlxTween.cancelTweensOf(this); + + HapticUtil.vibrate(0, 0.01, 0.2); + + animation.play('hold'); + } + + function playConfirmAnim():Void + { + FlxTween.cancelTweensOf(this); + HapticUtil.vibrate(0, 0.05, 0.5); + animation.play('confirm'); + FunkinSound.playOnce(Paths.sound('confirmMenu')); + + new FlxTimer().start(0.05, function(_) { + HapticUtil.vibrate(0, 0.01, 0.2); + }, 4); + + if (!instant) + { + animation.onFinish.add(function(name:String) { + onConfirmEnd.dispatch(); + }); + } + + onUp.remove(playConfirmAnim); + onDown.remove(playHoldAnim); + onOut.remove(playOutAnim); + } + + function playOutAnim():Void + { + FlxTween.cancelTweensOf(this); + HapticUtil.vibrate(0, 0.01, 0.2); + animation.play('idle'); + } + + override public function update(elapsed:Float):Void + { + super.update(elapsed); + + #if android + if (FlxG.android.justReleased.BACK) onDown.dispatch(); + #end + } +} From 9d3595c855220e938e77f9edd7b0fb71a5f1bc89 Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 21:20:16 +0100 Subject: [PATCH 07/17] implement new back button + options button to musicbeatstates --- source/funkin/ui/MusicBeatState.hx | 23 +++++++++++++++++++++-- source/funkin/ui/MusicBeatSubState.hx | 4 ++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/source/funkin/ui/MusicBeatState.hx b/source/funkin/ui/MusicBeatState.hx index 25b685624..da70ec012 100644 --- a/source/funkin/ui/MusicBeatState.hx +++ b/source/funkin/ui/MusicBeatState.hx @@ -18,6 +18,7 @@ import funkin.graphics.FunkinCamera; import funkin.mobile.ui.FunkinHitbox; import funkin.mobile.input.PreciseInputHandler; import funkin.mobile.ui.FunkinBackButton; +import funkin.mobile.ui.mainmenu.FunkinOptionsButton; import funkin.play.notes.NoteDirection; #end @@ -67,6 +68,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler #if mobile public var hitbox:Null; public var backButton:Null; + public var optionsButton:Null; public var camControls:Null; public function addHitbox(visible:Bool = true, initInput:Bool = true, ?schemeOverride:String, ?directionsOverride:Array, @@ -95,7 +97,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler } public function addBackButton(?xPos:Float = 0, ?yPos:Float = 0, ?color:FlxColor = FlxColor.WHITE, ?confirmCallback:Void->Void = null, - ?restOpacity:Float = 0.3):Void + ?restOpacity:Float = 0.3, ?instant:Bool = false):Void { if (backButton != null) remove(backButton); @@ -106,10 +108,27 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler camControls.bgColor = 0x0; } - backButton = new FunkinBackButton(xPos, yPos, color, confirmCallback, restOpacity); + backButton = new FunkinBackButton(xPos, yPos, color, confirmCallback, restOpacity, instant); backButton.cameras = [camControls]; add(backButton); } + + // this should get moved post ui update but this is easier rn lolll + public function addOptionsButton(?xPos:Float = 0, ?yPos:Float = 0, ?confirmCallback:Void->Void = null, ?instant:Bool = false):Void + { + if (optionsButton != null) remove(optionsButton); + + if (camControls == null) + { + camControls = new FunkinCamera('camControls'); + FlxG.cameras.add(camControls, false); + camControls.bgColor = 0x0; + } + + optionsButton = new FunkinOptionsButton(xPos, yPos, confirmCallback, instant); + optionsButton.cameras = [camControls]; + add(optionsButton); + } #end override function create() diff --git a/source/funkin/ui/MusicBeatSubState.hx b/source/funkin/ui/MusicBeatSubState.hx index 12f857656..42bf8d249 100644 --- a/source/funkin/ui/MusicBeatSubState.hx +++ b/source/funkin/ui/MusicBeatSubState.hx @@ -80,7 +80,7 @@ class MusicBeatSubState extends FlxSubState implements IEventHandler } public function addBackButton(?xPos:Float = 0, ?yPos:Float = 0, ?color:FlxColor = FlxColor.WHITE, ?confirmCallback:Void->Void = null, - ?restOpacity:Float = 0.3):Void + ?restOpacity:Float = 0.3, ?instant:Bool = false):Void { if (backButton != null) remove(backButton); @@ -91,7 +91,7 @@ class MusicBeatSubState extends FlxSubState implements IEventHandler camControls.bgColor = 0x0; } - backButton = new FunkinBackButton(xPos, yPos, color, confirmCallback, restOpacity); + backButton = new FunkinBackButton(xPos, yPos, color, confirmCallback, restOpacity, instant); backButton.cameras = [camControls]; add(backButton); } From b63e02d9e7fcf020009afe30d447c702414ef56b Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 21:20:32 +0100 Subject: [PATCH 08/17] make freeplay back button instant --- source/funkin/ui/freeplay/FreeplayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 250f645ff..6c89a6dd0 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -763,7 +763,7 @@ class FreeplayState extends MusicBeatSubState rankBg.alpha = 0; #if FEATURE_TOUCH_CONTROLS - addBackButton(FlxG.width, FlxG.height - 200, FlxColor.WHITE, goBack); + addBackButton(FlxG.width, FlxG.height - 200, FlxColor.WHITE, goBack, 0.3, true); FlxTween.tween(backButton, {x: FlxG.width - 230}, 0.5, {ease: FlxEase.expoOut}); #end From 2771a13d5e5c862c00c86e55d16e4d250209218d Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 21:20:54 +0100 Subject: [PATCH 09/17] tweak behavior for main menu items on mobile --- source/funkin/ui/MenuList.hx | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/source/funkin/ui/MenuList.hx b/source/funkin/ui/MenuList.hx index 652aa4d07..874e7b877 100644 --- a/source/funkin/ui/MenuList.hx +++ b/source/funkin/ui/MenuList.hx @@ -9,6 +9,9 @@ import funkin.audio.FunkinSound; import funkin.util.TouchUtil; import funkin.util.SwipeUtil; import funkin.ui.Page.PageName; +import flixel.tweens.FlxEase; +import funkin.util.HapticUtil; +import flixel.tweens.FlxTween; class MenuTypedList extends FlxTypedGroup { @@ -146,6 +149,8 @@ class MenuTypedList extends FlxTypedGroup if (item.available && isTouchingItem && TouchUtil.justPressed) { + var prevIndex:Int = selectedIndex; + if (!_isMainMenuState && selectedIndex != i) { newIndex = i; @@ -153,9 +158,34 @@ class MenuTypedList extends FlxTypedGroup } else { + FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); selectItem(i); } - accept(); + + if (_isMainMenuState) + { + if (prevIndex == i) + { + FlxTween.cancelTweensOf(item); + item.scale.set(1.1, 1.1); + FlxTween.tween(item.scale, {x: 1, y: 1}, 0.3, {ease: FlxEase.backOut}); + + HapticUtil.vibrate(0, 0.05, 0.5); + accept(); + } + else + { + FlxTween.cancelTweensOf(item); + item.scale.set(0.94, 0.94); + FlxTween.tween(item.scale, {x: 1, y: 1}, 0.3, {ease: FlxEase.backOut}); + + HapticUtil.vibrate(0, 0.01, 0.2); + } + } + else + { + accept(); + } break; } From edc668dad5efc891658403df7d2887f46a94c610 Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 21:21:09 +0100 Subject: [PATCH 10/17] add options button to main menu + upgrade button tweaks --- source/funkin/ui/mainmenu/MainMenuState.hx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index e6cbe2947..f42ccd2fe 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -47,7 +47,7 @@ class MainMenuState extends MusicBeatState // TODO: this needs to eventually reflect the actual state of whether the player has upgraded or not. // this should never be false on non-mobile targets. - var hasUpgraded:Bool = true; + var hasUpgraded:Bool = false; var upgradeSparkles:FlxTypedSpriteGroup; public function new(?_overrideMusic:Bool = false) @@ -154,9 +154,11 @@ class MainMenuState extends MusicBeatState #end #end + #if !mobile createMenuItem('options', 'mainmenu/options', function() { startExitState(() -> new funkin.ui.options.OptionsState()); }); + #end if (!hasUpgraded) { @@ -196,7 +198,7 @@ class MainMenuState extends MusicBeatState if (!hasUpgraded) { // the upgrade item - var targetItem = menuItems.members[4]; + var targetItem = menuItems.members[2]; for (i in 0...8) { var sparkle:UpgradeSparkle = new UpgradeSparkle(targetItem.x - (targetItem.width / 2), targetItem.y - (targetItem.height / 2), targetItem.width, @@ -232,7 +234,12 @@ class MainMenuState extends MusicBeatState // FlxG.camera.setScrollBounds(bg.x, bg.x + bg.width, bg.y, bg.y + bg.height * 1.2); #if mobile + camFollow.y = 355; + addBackButton(FlxG.width - 230, FlxG.height - 200, FlxColor.WHITE, goBack, 1.0); + addOptionsButton(35, FlxG.height - 210, function() { + startExitState(() -> new funkin.ui.options.OptionsState()); + }); #end super.create(); @@ -358,6 +365,11 @@ class MainMenuState extends MusicBeatState } }); + #if mobile + FlxTween.tween(optionsButton, {alpha: 0}, duration, {ease: FlxEase.quadOut}); + FlxTween.tween(backButton, {alpha: 0}, duration, {ease: FlxEase.quadOut}); + #end + new FlxTimer().start(duration, function(_) FlxG.switchState(state)); } From aa8f5087b5187f78ce61ada276bb1ac8a2a9f7ee Mon Sep 17 00:00:00 2001 From: fabs Date: Mon, 9 Jun 2025 21:43:28 +0100 Subject: [PATCH 11/17] set upgraded to true on pc always --- source/funkin/ui/mainmenu/MainMenuState.hx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index f42ccd2fe..2ed48f72d 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -67,6 +67,11 @@ class MainMenuState extends MusicBeatState transIn = FlxTransitionableState.defaultTransIn; transOut = FlxTransitionableState.defaultTransOut; + #if !mobile + // just to make sure its never accidentally turned off + hasUpgraded = true; + #end + if (!overrideMusic) playMenuMusic(); // We want the state to always be able to begin with being able to accept inputs and show the anims of the menu items. From 2450961b2844d3ec1335439a0e09b293cbe4f625 Mon Sep 17 00:00:00 2001 From: MoonDroid <81515012+moondroidcoder@users.noreply.github.com> Date: Tue, 10 Jun 2025 17:13:04 +0700 Subject: [PATCH 12/17] Add IAP functionality to the upgrade item in Main Menu --- source/funkin/mobile/util/AdMobUtil.hx | 5 +++ source/funkin/ui/mainmenu/MainMenuState.hx | 49 ++++++++++++---------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/source/funkin/mobile/util/AdMobUtil.hx b/source/funkin/mobile/util/AdMobUtil.hx index be1fdecbf..189cf2355 100644 --- a/source/funkin/mobile/util/AdMobUtil.hx +++ b/source/funkin/mobile/util/AdMobUtil.hx @@ -141,6 +141,7 @@ class AdMobUtil */ public static inline function addBanner(size:Int = AdmobBannerSize.BANNER, align:Int = AdmobBannerAlign.BOTTOM_CENTER):Void { + if (InAppPurchasesUtil.isPurchased("no_ads")) return; Admob.showBanner([AdMobUtil.ADMOB_PUBLISHER, AdMobUtil.BANNER_AD_UNIT_ID].join('/'), size, align); } @@ -159,6 +160,8 @@ class AdMobUtil */ public static function loadInterstitial(onInterstitialFinish:Void->Void):Void { + if (InAppPurchasesUtil.isPurchased("no_ads")) return; + function interstitialEvent(event:AdmobEvent):Void { if (event.name == AdmobEvent.INTERSTITIAL_LOADED) @@ -187,6 +190,8 @@ class AdMobUtil */ public static function loadRewarded(onRewardedFinish:Void->Void):Void { + if (InAppPurchasesUtil.isPurchased("no_ads")) return; + function rewardedEvent(event:AdmobEvent):Void { if (event.name == AdmobEvent.REWARDED_LOADED) diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index 2ed48f72d..f56fe2434 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -33,6 +33,9 @@ import funkin.api.discord.DiscordClient; #if FEATURE_NEWGROUNDS import funkin.api.newgrounds.NewgroundsClient; #end +#if mobile +import funkin.mobile.util.InAppPurchasesUtil; +#end class MainMenuState extends MusicBeatState { @@ -67,7 +70,9 @@ class MainMenuState extends MusicBeatState transIn = FlxTransitionableState.defaultTransIn; transOut = FlxTransitionableState.defaultTransOut; - #if !mobile + #if mobile + hasUpgraded = InAppPurchasesUtil.isPurchased("no_ads"); + #else // just to make sure its never accidentally turned off hasUpgraded = true; #end @@ -149,15 +154,28 @@ class MainMenuState extends MusicBeatState })); }); - #if FEATURE_OPEN_URL - // In order to prevent popup blockers from triggering, - // we need to open the link as an immediate result of a keypress event, - // so we can't wait for the flicker animation to complete. - var hasPopupBlocker = #if web true #else false #end; - #if desktop - createMenuItem('merch', 'mainmenu/merch', selectMerch, hasPopupBlocker); - #end - #end + if (hasUpgraded) + { + #if FEATURE_OPEN_URL + // In order to prevent popup blockers from triggering, + // we need to open the link as an immediate result of a keypress event, + // so we can't wait for the flicker animation to complete. + var hasPopupBlocker = #if web true #else false #end; + createMenuItem('merch', 'mainmenu/merch', selectMerch, hasPopupBlocker); + #end + } + else + { + upgradeSparkles = new FlxTypedSpriteGroup(); + add(upgradeSparkles); + + createMenuItem('upgrade', 'mainmenu/upgrade', function() { + #if mobile + InAppPurchasesUtil.purchase("no_ads"); + FlxG.resetState(); + #end + }); + } #if !mobile createMenuItem('options', 'mainmenu/options', function() { @@ -165,17 +183,6 @@ class MainMenuState extends MusicBeatState }); #end - if (!hasUpgraded) - { - upgradeSparkles = new FlxTypedSpriteGroup(); - add(upgradeSparkles); - - createMenuItem('upgrade', 'mainmenu/upgrade', function() { - // TODO: this needs to actually lead you to the purchase screen - startExitState(() -> new funkin.ui.options.OptionsState()); - }); - } - createMenuItem('credits', 'mainmenu/credits', function() { startExitState(() -> new funkin.ui.credits.CreditsState()); }); From bc94a5a6ac5ff73720301b93ef3a1c17cc9fd1e0 Mon Sep 17 00:00:00 2001 From: MoonDroid <81515012+moondroidcoder@users.noreply.github.com> Date: Tue, 10 Jun 2025 17:13:56 +0700 Subject: [PATCH 13/17] fix: Remove control schemes and add back button into Options --- source/funkin/ui/options/OptionsState.hx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/source/funkin/ui/options/OptionsState.hx b/source/funkin/ui/options/OptionsState.hx index 55f7b3944..425d22ff2 100644 --- a/source/funkin/ui/options/OptionsState.hx +++ b/source/funkin/ui/options/OptionsState.hx @@ -108,15 +108,11 @@ class OptionsMenu extends Page createItem("PREFERENCES", function() codex.switchPage(Preferences)); #if mobile if (FlxG.gamepads.numActiveGamepads > 0) - { - createItem("CONTROLS", function() codex.switchPage(Controls)); - } - createItem("CONTROL SCHEMES", function() { - FlxG.state.openSubState(new ControlsSchemeMenu()); - }); - #else - createItem("CONTROLS", function() codex.switchPage(Controls)); #end + createItem("CONTROLS", function() codex.switchPage(Controls)); + // createItem("CONTROL SCHEMES", function() { + // FlxG.state.openSubState(new ControlsSchemeMenu()); + // }); createItem("INPUT OFFSETS", function() { OptionsState.rememberedSelectedIndex = items.selectedIndex; #if web @@ -161,7 +157,12 @@ class OptionsMenu extends Page createItem("CLEAR SAVE DATA", function() { promptClearSaveData(); }); + #if NO_FEATURE_TOUCH_CONTROLS createItem("EXIT", exit); + #else + var backButton:FunkinBackButton = new FunkinBackButton(FlxG.width - 230, FlxG.height - 200, exit, 1.0); + add(backButton); + #end items.selectItem(OptionsState.rememberedSelectedIndex); } From 031f888a2506bcf8b1135bb5ac571a30bc20f8c8 Mon Sep 17 00:00:00 2001 From: MoonDroid <81515012+moondroidcoder@users.noreply.github.com> Date: Tue, 10 Jun 2025 17:14:52 +0700 Subject: [PATCH 14/17] Remove debug display, pause on unfocus, and FPS from Mobile --- source/funkin/ui/options/PreferencesMenu.hx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/funkin/ui/options/PreferencesMenu.hx b/source/funkin/ui/options/PreferencesMenu.hx index 798d520e0..09d84d026 100644 --- a/source/funkin/ui/options/PreferencesMenu.hx +++ b/source/funkin/ui/options/PreferencesMenu.hx @@ -139,13 +139,13 @@ class PreferencesMenu extends Page createPrefItemCheckbox('Camera Zooms', 'If disabled, camera stops bouncing to the song.', function(value:Bool):Void { Preferences.zoomCamera = value; }, Preferences.zoomCamera); + #if !mobile createPrefItemCheckbox('Debug Display', 'If enabled, FPS and other debug stats will be displayed.', function(value:Bool):Void { Preferences.debugDisplay = value; }, Preferences.debugDisplay); createPrefItemCheckbox('Pause on Unfocus', 'If enabled, game automatically pauses when it loses focus.', function(value:Bool):Void { Preferences.autoPause = value; }, Preferences.autoPause); - #if !mobile createPrefItemCheckbox('Launch in Fullscreen', 'Automatically launch the game in fullscreen on startup', function(value:Bool):Void { Preferences.autoFullscreen = value; }, Preferences.autoFullscreen); @@ -173,10 +173,12 @@ class PreferencesMenu extends Page case WindowVSyncMode.ADAPTIVE: "Adaptive"; }); #end + #if !mobile createPrefItemNumber('FPS', 'The maximum framerate that the game targets.', function(value:Float) { Preferences.framerate = Std.int(value); }, null, Preferences.framerate, 30, 500, 5, 0); #end + #end #if FEATURE_SCREENSHOTS createPrefItemCheckbox('Hide Mouse', 'If enabled, the mouse will be hidden when taking a screenshot.', function(value:Bool):Void { From b0f4a075b56547bdf6d8cfd905090783a4d02727 Mon Sep 17 00:00:00 2001 From: MoonDroid <81515012+moondroidcoder@users.noreply.github.com> Date: Tue, 10 Jun 2025 17:15:12 +0700 Subject: [PATCH 15/17] fix: Tweak back button position in Preferences --- source/funkin/ui/options/PreferencesMenu.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/ui/options/PreferencesMenu.hx b/source/funkin/ui/options/PreferencesMenu.hx index 09d84d026..24d3fd791 100644 --- a/source/funkin/ui/options/PreferencesMenu.hx +++ b/source/funkin/ui/options/PreferencesMenu.hx @@ -76,8 +76,8 @@ class PreferencesMenu extends Page itemDesc.text = preferenceDesc[items.selectedIndex]; }); - #if mobile - var backButton:FunkinBackButton = new FunkinBackButton(FlxG.width * 0.83, FlxG.height * 0.75, exit); + #if FEATURE_TOUCH_CONTROLS + var backButton:FunkinBackButton = new FunkinBackButton(FlxG.width - 230, FlxG.height - 200, exit, 1.0); add(backButton); #end } From 9303e4c2724787efa0246df4e31e6d36be48dbf8 Mon Sep 17 00:00:00 2001 From: MoonDroid <81515012+moondroidcoder@users.noreply.github.com> Date: Tue, 10 Jun 2025 17:15:41 +0700 Subject: [PATCH 16/17] Force FPS, pause on unfocus, and debug display to be a set value on mobile --- source/funkin/Preferences.hx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/source/funkin/Preferences.hx b/source/funkin/Preferences.hx index f89a5e202..030ce9810 100644 --- a/source/funkin/Preferences.hx +++ b/source/funkin/Preferences.hx @@ -14,6 +14,7 @@ class Preferences { /** * FPS + * Always the refresh rate of the display on mobile, or 60 on web. * @default `60` */ public static var framerate(get, set):Int; @@ -27,7 +28,7 @@ class Preferences if (refreshRate < 60) refreshRate = 60; - return Save?.instance?.options?.framerate ?? refreshRate; + return refreshRate; #else return Save?.instance?.options?.framerate ?? 60; #end @@ -125,12 +126,16 @@ class Preferences /** * If enabled, an FPS and memory counter will be displayed even if this is not a debug build. + * Always disabled on mobile. * @default `false` */ public static var debugDisplay(get, set):Bool; static function get_debugDisplay():Bool { + #if mobile + return false; + #end return Save?.instance?.options?.debugDisplay; } @@ -190,12 +195,16 @@ class Preferences /** * If enabled, the game will automatically pause when tabbing out. + * Always enabled on mobile. * @default `true` */ public static var autoPause(get, set):Bool; static function get_autoPause():Bool { + #if mobile + return true; + #end return Save?.instance?.options?.autoPause ?? true; } From 753f51dcf6659b4dcbff06d306fde9cab0901d2a Mon Sep 17 00:00:00 2001 From: MoonDroid <81515012+moondroidcoder@users.noreply.github.com> Date: Tue, 10 Jun 2025 17:31:58 +0700 Subject: [PATCH 17/17] assets submod two --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index aa426c217..422f7d573 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit aa426c217aa5236ef14e7fb55f5bf99a09d56d58 +Subproject commit 422f7d57381ca128978dae70f5a1b32da9a2b2cc