From ec3b8c54497797096821d3a871208d756c0ea49b Mon Sep 17 00:00:00 2001 From: richTrash21 <87835336+richTrash21@users.noreply.github.com> Date: Fri, 3 Jan 2025 03:51:54 +0400 Subject: [PATCH] add FlxG.center() and FlxCamera.center() --- flixel/FlxCamera.hx | 44 +++++++++++++++ flixel/FlxG.hx | 47 +++++++++++++++- flixel/FlxObject.hx | 15 ++---- tests/unit/src/flixel/FlxCameraTest.hx | 75 +++++++++++++++++++++++++- tests/unit/src/flixel/FlxGTest.hx | 67 +++++++++++++++++++++++ tests/unit/src/flixel/FlxObjectTest.hx | 9 ++-- 6 files changed, 241 insertions(+), 16 deletions(-) diff --git a/flixel/FlxCamera.hx b/flixel/FlxCamera.hx index 6a29052544..39604eb47f 100644 --- a/flixel/FlxCamera.hx +++ b/flixel/FlxCamera.hx @@ -1901,6 +1901,50 @@ class FlxCamera extends FlxBasic setScale(scaleX, scaleY); } + /** + * Centers `FlxSprite` by graphic size in this camera view, either by the x axis, y axis, or both. + * + * @param sprite The sprite to center. + * @param axes On what axes to center the sprite (e.g. `X`, `Y`, `XY`) - default is both. + * @return Centered sprite for chaining. + * @since TBA + */ + public function center(sprite:T, axes:FlxAxes = XY):T + { + if (axes.x) + { + final graphicWidth = sprite.frameWidth * Math.abs(sprite.scale.x); + sprite.x = viewX + (viewWidth - graphicWidth) / 2; + } + + if (axes.y) + { + final graphicHeight = sprite.frameHeight * Math.abs(sprite.scale.y); + sprite.y = viewY + (viewHeight - graphicHeight) / 2; + } + + return sprite; + } + + /** + * Centers `FlxObject` by hitbox size in this camera view, either by the x axis, y axis, or both. + * + * @param sprite The object to center. + * @param axes On what axes to center the object (e.g. `X`, `Y`, `XY`) - default is both. + * @return Centered object for chaining. + * @since TBA + */ + public function centerHitbox(object:T, axes:FlxAxes = XY):T + { + if (axes.x) + object.x = viewX + (viewWidth - object.width) / 2; + + if (axes.y) + object.y = viewY + (viewHeight - object.height) / 2; + + return object; + } + /** * The size and position of this camera's margins, via `viewMarginLeft`, `viewMarginTop`, `viewWidth` * and `viewHeight`. diff --git a/flixel/FlxG.hx b/flixel/FlxG.hx index 912532fdcb..c738c108a4 100644 --- a/flixel/FlxG.hx +++ b/flixel/FlxG.hx @@ -21,6 +21,7 @@ import flixel.system.frontEnds.VCRFrontEnd; import flixel.system.frontEnds.WatchFrontEnd; import flixel.system.scaleModes.BaseScaleMode; import flixel.system.scaleModes.RatioScaleMode; +import flixel.util.FlxAxes; import flixel.util.FlxCollision; import flixel.util.FlxSave; import flixel.util.typeLimit.NextState; @@ -510,7 +511,51 @@ class FlxG { return overlap(objectOrGroup1, objectOrGroup2, notifyCallback, FlxObject.separate); } - + + /** + * Centers `FlxSprite` by graphic size in game space, either by the x axis, y axis, or both. + * + * @param sprite The sprite to center. + * @param axes On what axes to center the sprite (e.g. `X`, `Y`, `XY`) - default is both. + * @return Centered sprite for chaining. + * @since TBA + */ + public static function center(sprite:T, axes:FlxAxes = XY):T + { + if (axes.x) + { + final graphicWidth = sprite.frameWidth * Math.abs(sprite.scale.x); + sprite.x = (FlxG.width - graphicWidth) / 2; + } + + if (axes.y) + { + final graphicHeight = sprite.frameHeight * Math.abs(sprite.scale.y); + sprite.y = (FlxG.height - graphicHeight) / 2; + } + + return sprite; + } + + /** + * Centers `FlxObject` by hitbox size in game space, either by the x axis, y axis, or both. + * + * @param sprite The object to center. + * @param axes On what axes to center the object (e.g. `X`, `Y`, `XY`) - default is both. + * @return Centered object for chaining. + * @since TBA + */ + public static function centerHitbox(object:T, axes:FlxAxes = XY):T + { + if (axes.x) + object.x = (FlxG.width - object.width) / 2; + + if (axes.y) + object.y = (FlxG.height - object.height) / 2; + + return object; + } + /** * Regular `DisplayObject`s are normally displayed over the Flixel cursor and the Flixel debugger if simply * added to `stage`. This function simplifies things by adding a `DisplayObject` directly below mouse level. diff --git a/flixel/FlxObject.hx b/flixel/FlxObject.hx index 21f5795b88..86adf8bdcf 100644 --- a/flixel/FlxObject.hx +++ b/flixel/FlxObject.hx @@ -1256,24 +1256,19 @@ class FlxObject extends FlxBasic kill(); } #end - + /** * Centers this `FlxObject` on the screen, either by the x axis, y axis, or both. - * + * * @param axes On what axes to center the object (e.g. `X`, `Y`, `XY`) - default is both. * @return This FlxObject for chaining */ + @:deprecated("screenCenter is deprecated, use FlxG.centerHitbox instead") public inline function screenCenter(axes:FlxAxes = XY):FlxObject { - if (axes.x) - x = (FlxG.width - width) / 2; - - if (axes.y) - y = (FlxG.height - height) / 2; - - return this; + return FlxG.centerHitbox(this, axes); } - + /** * Helper function to set the coordinates of this object. * Handy since it only requires one line of code. diff --git a/tests/unit/src/flixel/FlxCameraTest.hx b/tests/unit/src/flixel/FlxCameraTest.hx index 62eeb63819..5b2059a5e0 100644 --- a/tests/unit/src/flixel/FlxCameraTest.hx +++ b/tests/unit/src/flixel/FlxCameraTest.hx @@ -1,5 +1,6 @@ package flixel; +import flixel.math.FlxPoint; import flixel.util.FlxColor; import massive.munit.Assert; @@ -89,7 +90,79 @@ class FlxCameraTest extends FlxTest camera.follow(new FlxObject()); Assert.areEqual(defaultLerp, camera.followLerp); } - + + @Test + function testCenter() + { + final sprite = new FlxSprite(); + sprite.makeGraphic(10, 10); + sprite.scale.set(-2, -4); + final cam = FlxG.camera; + cam.scroll.set(100, 100); + cam.zoom *= 2; + final graphicWidth = sprite.frameWidth * Math.abs(sprite.scale.x); + final graphicHeight = sprite.frameHeight * Math.abs(sprite.scale.y); + final center = FlxPoint.get(cam.viewX + (cam.viewWidth - graphicWidth) / 2, cam.viewY + (cam.viewHeight - graphicHeight) / 2); + final offCenter = center.copyTo().add(1000, 1000); + + sprite.setPosition(offCenter.x, offCenter.y); + cam.center(sprite, X); + Assert.areEqual(sprite.x, center.x); + Assert.areEqual(sprite.y, offCenter.y); + + sprite.setPosition(offCenter.x, offCenter.y); + cam.center(sprite, Y); + Assert.areEqual(sprite.x, offCenter.x); + Assert.areEqual(sprite.y, center.y); + + sprite.setPosition(offCenter.x, offCenter.y); + cam.center(sprite, XY); + Assert.areEqual(sprite.x, center.x); + Assert.areEqual(sprite.y, center.y); + + sprite.setPosition(offCenter.x, offCenter.y); + cam.center(sprite); + Assert.areEqual(sprite.x, center.x); + Assert.areEqual(sprite.y, center.y); + + offCenter.put(); + center.put(); + } + + @Test + function testCenterHitbox() + { + final object = new FlxObject(0, 0, 10, 10); + final cam = FlxG.camera; + cam.scroll.set(100, 100); + cam.zoom *= 2; + final center = FlxPoint.get(cam.viewX + (cam.viewWidth - object.width) / 2, cam.viewY + (cam.viewHeight - object.height) / 2); + final offCenter = center.copyTo().add(1000, 1000); + + object.setPosition(offCenter.x, offCenter.y); + cam.centerHitbox(object, X); + Assert.areEqual(object.x, center.x); + Assert.areEqual(object.y, offCenter.y); + + object.setPosition(offCenter.x, offCenter.y); + cam.centerHitbox(object, Y); + Assert.areEqual(object.x, offCenter.x); + Assert.areEqual(object.y, center.y); + + object.setPosition(offCenter.x, offCenter.y); + cam.centerHitbox(object, XY); + Assert.areEqual(object.x, center.x); + Assert.areEqual(object.y, center.y); + + object.setPosition(offCenter.x, offCenter.y); + cam.centerHitbox(object); + Assert.areEqual(object.x, center.x); + Assert.areEqual(object.y, center.y); + + offCenter.put(); + center.put(); + } + @Test function testFadeInFadeOut() { diff --git a/tests/unit/src/flixel/FlxGTest.hx b/tests/unit/src/flixel/FlxGTest.hx index 58d3daac76..b24082c5c0 100644 --- a/tests/unit/src/flixel/FlxGTest.hx +++ b/tests/unit/src/flixel/FlxGTest.hx @@ -1,5 +1,6 @@ package flixel; +import flixel.math.FlxPoint; import massive.munit.Assert; @:access(flixel.FlxG) @@ -104,4 +105,70 @@ class FlxGTest extends FlxTest { Assert.areEqual(480, FlxG.height); } + + @Test + function testCenter() + { + final sprite = new FlxSprite(); + sprite.makeGraphic(10, 10); + sprite.scale.set(-2, -4); + final graphicWidth = sprite.frameWidth * Math.abs(sprite.scale.x); + final graphicHeight = sprite.frameHeight * Math.abs(sprite.scale.y); + final center = FlxPoint.get((FlxG.width - graphicWidth) / 2, (FlxG.height - graphicHeight) / 2); + final offCenter = center.copyTo().add(1000, 1000); + + sprite.setPosition(offCenter.x, offCenter.y); + FlxG.center(sprite, X); + Assert.areEqual(sprite.x, center.x); + Assert.areEqual(sprite.y, offCenter.y); + + sprite.setPosition(offCenter.x, offCenter.y); + FlxG.center(sprite, Y); + Assert.areEqual(sprite.x, offCenter.x); + Assert.areEqual(sprite.y, center.y); + + sprite.setPosition(offCenter.x, offCenter.y); + FlxG.center(sprite, XY); + Assert.areEqual(sprite.x, center.x); + Assert.areEqual(sprite.y, center.y); + + sprite.setPosition(offCenter.x, offCenter.y); + FlxG.center(sprite); + Assert.areEqual(sprite.x, center.x); + Assert.areEqual(sprite.y, center.y); + + offCenter.put(); + center.put(); + } + + @Test + function testCenterHitbox() + { + final object = new FlxObject(0, 0, 10, 10); + final center = FlxPoint.get((FlxG.width - object.width) / 2, (FlxG.height - object.height) / 2); + final offCenter = center.copyTo().add(1000, 1000); + + object.setPosition(offCenter.x, offCenter.y); + FlxG.centerHitbox(object, X); + Assert.areEqual(object.x, center.x); + Assert.areEqual(object.y, offCenter.y); + + object.setPosition(offCenter.x, offCenter.y); + FlxG.centerHitbox(object, Y); + Assert.areEqual(object.x, offCenter.x); + Assert.areEqual(object.y, center.y); + + object.setPosition(offCenter.x, offCenter.y); + FlxG.centerHitbox(object, XY); + Assert.areEqual(object.x, center.x); + Assert.areEqual(object.y, center.y); + + object.setPosition(offCenter.x, offCenter.y); + FlxG.centerHitbox(object); + Assert.areEqual(object.x, center.x); + Assert.areEqual(object.y, center.y); + + offCenter.put(); + center.put(); + } } diff --git a/tests/unit/src/flixel/FlxObjectTest.hx b/tests/unit/src/flixel/FlxObjectTest.hx index 6fe89c7865..5454eb9285 100644 --- a/tests/unit/src/flixel/FlxObjectTest.hx +++ b/tests/unit/src/flixel/FlxObjectTest.hx @@ -341,6 +341,7 @@ class FlxObjectTest extends FlxTest } @Test + @:haxe.warning("-WDeprecated") // TODO: remove this test? function testScreenCenter() { var center = FlxPoint.get((FlxG.width - object1.width) / 2, (FlxG.height - object1.height) / 2); @@ -350,17 +351,17 @@ class FlxObjectTest extends FlxTest object1.screenCenter(X); Assert.areEqual(object1.x, center.x); Assert.areEqual(object1.y, offCenter.y); - + object1.setPosition(offCenter.x, offCenter.y); object1.screenCenter(Y); Assert.areEqual(object1.x, offCenter.x); Assert.areEqual(object1.y, center.y); - + object1.setPosition(offCenter.x, offCenter.y); object1.screenCenter(XY); Assert.areEqual(object1.x, center.x); Assert.areEqual(object1.y, center.y); - + object1.setPosition(offCenter.x, offCenter.y); object1.screenCenter(); Assert.areEqual(object1.x, center.x); @@ -369,7 +370,7 @@ class FlxObjectTest extends FlxTest offCenter.put(); center.put(); } - + @Test function testgetRotatedBounds() {