Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hit area is offset from expected when using scaled sprite with a provided hit rectangle. #6317

Closed
justinlueders opened this issue Dec 10, 2022 · 4 comments

Comments

@justinlueders
Copy link

justinlueders commented Dec 10, 2022

  • Phaser Version:

phaser@3.60.0-beta.17

  • Operating system:

windows 10

Description

Adding an image with a scale and custom hit area generates a hit area offset from the expected hit area shown with enableDebug.

In the example the debug rect is red and the actual hit area is surrounded by a green rect.

I believe the position values are getting scaled along with the size of the sprite for the hit detection.

A workaround (included in commented code below) is to use a custom callback and remove the scale from the position values during the check.

Example Test Code

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/phaser@3.60.0-beta.17/dist/phaser-arcade-physics.min.js"></script>
</head>
<body>
    <script>
    var game = new Phaser.Game({
        type: Phaser.AUTO,
        width: 800,
        height: 600,
        scene: {
            preload: preload,
            create: create
        }
    });

    function preload ()
    {
		this.load.setBaseURL('http://labs.phaser.io');
        this.load.image('image', 'assets/sprites/32x32.png');
	}

    function create ()
    {
		var image = new Phaser.GameObjects.Sprite(this, 400, 300, 'image');
		image.setInteractive({
		  draggable: true,
		  hitArea: new Phaser.Geom.Rectangle(10,10,20,20),
		  hitAreaCallback: Phaser.Geom.Rectangle.Contains
		});
		this.add.existing(image);
		image.setScale(3, 3);		
		image.setOrigin(0,0);
		this.input.enableDebug(image, 0xff0000);
		
		var actualHitArea = this.add.rectangle(image.x + 30, image.y + 30, 60, 60);
		actualHitArea.setOrigin(0,0);
		actualHitArea.setStrokeStyle(2, 0x00ff00);
		
		image.on('drag', function (pointer, dragX, dragY) {
			image.x = dragX;
			image.y = dragY;
		});
		image.on('pointerover', function () {
			this.setTint(0x00ff00);
		});
		image.on('pointerout', function () {
			this.clearTint();
		});
	}
  /* A workaround for this is to replace the callback with this that rolls back the scale on the position.
  hitAreaCallback: function (rect, x, y, gameObject)
  {
	if (rect.width <= 0 || rect.height <= 0)
	{
		return false;
	}
	var scaleOffsetX = rect.x/gameObject.scaleX;
	var scaleOffsetY = rect.y/gameObject.scaleY;
	return (scaleOffsetX <= x && scaleOffsetX + rect.width >= x && scaleOffsetY <= y && scaleOffsetY + rect.height >= y);
  }*/
    </script>
</body>
</html>
@photonstorm
Copy link
Collaborator

Duplicate of #4905 I think?

@justinlueders
Copy link
Author

Ah yeah not sure how I missed that one. This one can be closed. I did create a work around and believe that the position of the actual hit area is getting scaled. If you remove the scale during the hit test it works as expected.

@photonstorm
Copy link
Collaborator

Yeah, I'll have a look at that for the next beta release.

@photonstorm
Copy link
Collaborator

Thank you for submitting this issue. We have fixed this and the fix has been pushed to the master branch. It will be part of the next release. If you get time to build and test it for yourself we would appreciate that.

photonstorm added a commit that referenced this issue Dec 12, 2022
…ncorrectly offset if the Game Object was attached to was scaled and the hit area shape was smaller, or offset, from the Game Object. Fix #4905 #6317
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants