HaxeFlixel / flixel

Free, cross-platform 2D game engine powered by Haxe and OpenFL
https://haxeflixel.com/
MIT License
1.93k stars 427 forks source link

Fix getGraphicMidpoint() in FlxSprite #3101

Closed ThatRozebudDude closed 2 months ago

ThatRozebudDude commented 2 months ago

Currently, if you use getGraphicMidpoint() on an FlxSprite that has been scaled it will return the midpoint of the sprite as if it was not scaled. This pull request fixes this by multiplying the midpoint by the sprite's scale.

This image shows the current behavior of getGraphicMidpoint (red) vs the changed behavior (cyan) on various scaled boxes. image The first box has a scale of 1 so both points are the same. If you measure the distance between the top left corner and the red square, the distance is the same for each box.

Geokureli commented 2 months ago

can you share the code used to create those images, so that I can quickly replicate this issue on my machine. this PR looks solid at a glance but I try to manually verify whenever I can

ThatRozebudDude commented 2 months ago

Here is the code for the test that I wrote.

package;

import flixel.math.FlxPoint;
import flixel.FlxSprite;
import flixel.FlxState;

class MidpointTest extends FlxState
{

    override function create()
    {

        var sizes:Array<Array<Float>> = [[1, 1], [0.9, 0.9], [0.6, 1.3], [0.7, 0.8], [1.4, 1.2]];

        for(i in 0...sizes.length){
            var box = new FlxSprite((i+1) * (1280/(sizes.length + 2)), 0).makeGraphic(72, 72, 0xFFFFFFFF);
            box.screenCenter(Y);
            box.setGraphicSize(box.width * sizes[i][0], box.height * sizes[i][1]);
            box.updateHitbox();
            add(box);

            var wrong = new FlxSprite(box.getGraphicMidpoint().x, box.getGraphicMidpoint().y).makeGraphic(8, 8, 0xFFFF0000);
            wrong.centerOffsets();
            add(wrong);

            var correct = new FlxSprite(getGraphicMidpointFix(box).x, getGraphicMidpointFix(box).y).makeGraphic(8, 8, 0xFF00FFFF);
            correct.centerOffsets();
            add(correct);
        }

        super.create();
    }

    function getGraphicMidpointFix(sprite:FlxSprite, ?point:FlxPoint):FlxPoint{
    if (point == null){
        point = FlxPoint.get();
    }
    return point.set(sprite.x + sprite.frameWidth * 0.5 * sprite.scale.x, sprite.y + sprite.frameHeight * 0.5 * sprite.scale.y);
    }

}
Geokureli commented 2 months ago

Thanks!