1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2025-12-09 05:29:12 +00:00

Prevent the game bounds from breaking when resizing the window

This commit is contained in:
Karim Akra 2025-11-15 17:43:51 +02:00 committed by Kade
parent 5d76d23d33
commit 38634ef5ca
2 changed files with 113 additions and 2 deletions

View file

@ -4,10 +4,13 @@ import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
import flixel.math.FlxPoint;
import flixel.util.FlxAxes;
import flixel.util.FlxHorizontalAlign;
import flixel.util.FlxVerticalAlign;
import flixel.FlxG;
import openfl.display.Bitmap;
import openfl.display.BitmapData;
import funkin.util.MathUtil;
import funkin.graphics.FunkinCamera;
class FullScreenScaleMode extends flixel.system.scaleModes.BaseScaleMode
{
@ -95,6 +98,15 @@ class FullScreenScaleMode extends flixel.system.scaleModes.BaseScaleMode
@:noCompletion
private static var cutoutBitmaps:Array<Bitmap> = [null, null];
@:noCompletion
private static var mustAwait:Bool = false;
@:noCompletion
private static var awaitedSize:FlxPoint = FlxPoint.get(0, 0);
@:noCompletion
private static var finishingAwait:Bool = false;
/**
* Constructor for `FullScreenScaleMode`.
*
@ -119,6 +131,62 @@ class FullScreenScaleMode extends flixel.system.scaleModes.BaseScaleMode
*/
override public function onMeasure(Width:Int, Height:Int):Void
{
if (mustAwait)
{
onMeasureAwait(Width, Height);
}
else
{
onMeasureInstant(Width, Height);
mustAwait = true;
}
}
/**
* Locks the game to the current aspect ratio and assignes the requested resolution as awaited for later.
* @param Width The width of the screen.
* @param Height The height of the screen.
*/
public function onMeasureAwait(Width:Int, Height:Int):Void
{
horizontalAlign = CENTER;
verticalAlign = CENTER;
updateGameSize(FlxG.width, FlxG.height);
updateDeviceSize(Width, Height);
updateDeviceCutout(Width, Height);
#if mobile
updateDeviceNotch(funkin.mobile.util.ScreenUtil.getNotchRect());
#end
updateScaleOffset();
updateGamePosition();
awaitedSize.set(Width, Height);
}
/**
* Unlock the game resolution and swap into the awaited one.
*/
public function onMeasurePostAwait():Void
{
if (awaitedSize.x == 0 && awaitedSize.y == 0) return;
horizontalAlign = enabled ? LEFT : CENTER;
verticalAlign = enabled ? TOP : CENTER;
onMeasureInstant(Math.ceil(awaitedSize.x), Math.ceil(awaitedSize.y));
FlxG.cameras.reset(new FunkinCamera('default'));
awaitedSize.set(0, 0);
}
/**
* Instantly apply the measured resolution to the game
* @param Width The width of the screen.
* @param Height The height of the screen.
*/
public function onMeasureInstant(Width:Int, Height:Int):Void
{
finishingAwait = true;
untyped FlxG.width = FlxG.initialWidth;
untyped FlxG.height = FlxG.initialHeight;
@ -132,6 +200,8 @@ class FullScreenScaleMode extends flixel.system.scaleModes.BaseScaleMode
updateGamePosition();
adjustGameSize();
finishingAwait = false;
}
/**
@ -265,12 +335,50 @@ class FullScreenScaleMode extends flixel.system.scaleModes.BaseScaleMode
override public function updateScaleOffset():Void
{
scale.x = ratioAxis == X ? logicalSize.x / FlxG.width : deviceSize.x / FlxG.width;
scale.y = ratioAxis == Y ? logicalSize.y / FlxG.height : deviceSize.y / FlxG.height;
if (finishingAwait)
{
scale.x = ratioAxis == X ? logicalSize.x / FlxG.width : deviceSize.x / FlxG.width;
scale.y = ratioAxis == Y ? logicalSize.y / FlxG.height : deviceSize.y / FlxG.height;
}
else
{
scale.x = deviceSize.x / FlxG.width;
scale.y = deviceSize.y / FlxG.height;
if (scale.x > scale.y) scale.x = scale.y;
else
scale.y = scale.x;
}
updateOffsetX();
updateOffsetY();
}
override function updateOffsetX():Void
{
offset.x = switch (horizontalAlign)
{
case FlxHorizontalAlign.LEFT:
0;
case FlxHorizontalAlign.CENTER:
Math.ceil(finishingAwait ? (deviceSize.x - gameSize.x) : (deviceSize.x - (gameSize.x * scale.x)) * 0.5);
case FlxHorizontalAlign.RIGHT:
deviceSize.x - gameSize.x;
}
}
override function updateOffsetY():Void
{
offset.y = switch (verticalAlign)
{
case FlxVerticalAlign.TOP:
0;
case FlxVerticalAlign.CENTER:
Math.ceil(finishingAwait ? (deviceSize.y - gameSize.y) : (deviceSize.y - (gameSize.y * scale.y)) * 0.5);
case FlxVerticalAlign.BOTTOM:
deviceSize.y - gameSize.y;
}
}
#if mobile
private function updateDeviceNotch(notch:lime.math.Rectangle):Void
{

View file

@ -14,6 +14,7 @@ import funkin.modding.module.ModuleHandler;
import funkin.util.SortUtil;
import funkin.util.WindowUtil;
import funkin.input.Controls;
import funkin.ui.FullScreenScaleMode;
#if mobile
import funkin.graphics.FunkinCamera;
import funkin.mobile.ui.FunkinHitbox;
@ -55,6 +56,8 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler
public function new()
{
if (FullScreenScaleMode.instance != null) FullScreenScaleMode.instance.onMeasurePostAwait();
super();
initCallbacks();