phaserjs / phaser

Phaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.
https://phaser.io
MIT License
37.12k stars 7.1k forks source link

setOrigin(0, 0) is not in sync with Arcade Physics body #5079

Closed dsabsay closed 4 years ago

dsabsay commented 4 years ago

Version

Description

When creating a new Game Object on an Arcade Physics StaticGroup, using setOrigin(0, 0) seems to cause the associated physics body to be out of sync with where the sprite is drawn, which causes unexpected overlap/collision behavior. The "hitbox" appears to be accounting for the change in origin:

Screen Shot 2020-04-05 at 7 04 16 PM

This is related to #4052, where a fix was supposedly implemented. But it seems that fix doesn't cover creating game objects in this manner.

Example Test Code

This can be reproduced by opening this codepen (from #4052): https://codepen.io/samme/pen/vzMzBZ?editors=0010 and doing these steps:

  1. Change the Phaser version to 3.22.0 (Can be easily done in codepen settings. Don't forget to click Run afterward).
  2. Replace lines 34 and 35 with this:
    var block = this.physics.add.staticGroup();
    block.create(400, 100, 'block')

Additional Information

A workaround is to avoid using the StaticGroup, and just create e.g. Sprite objects directly. As such, I don't know if this is a major bug, but it is certainly unexpected behavior, in my opinion.

dsabsay commented 4 years ago

If you create the sprite object first and then add it to the StaticGroup, this issue doesn't seem to occur. For example:

const seeds = this.physics.add.staticGroup();
...
let seed = this.physics.add.sprite(mapX + o.x, mapY + o.y - tileSize, 'seed');
seed.setOrigin(0, 0);
seeds.add(seed);
...

The hitbox is correctly aligned in this case.

samme commented 4 years ago

I think you're seeing the expected behavior. You need to update the static body manually:

var group = this.physics.add.staticGroup();

group.create(200, 150, 'block').setOrigin(0, 0).refreshBody();

this.physics.add.staticImage(400, 150, 'block').setOrigin(0, 0).refreshBody();
photonstorm commented 4 years ago

You cannot alter a Static Body post-creation, because it's static. If you do change something, call refreshBody to re-sync the object with the body.

mohanvaddi commented 1 year ago

I'm having a similar issue, My gameObject is not in sync with the body. I am using a static matter sprite. I know I can use refreshBody to re-sync the object with body when using Arcade sprite.

Is there a method to do the same thing as refreshBody in this case where I'm using static matter sprite:

        const block = this.matter.add.sprite(x, y, TextureKeys.BLOCK, undefined, {
          isStatic: true,
        })
          .setSize(blockWidth, blockheight)
          .setTint(this.getRandomColor())
          .setOrigin(0);
photonstorm commented 1 year ago

@mohanvaddi your issue isn't similar because it's not using Arcade Physics. This issue is 2 years old. If you need some help, you need to open your own - although, as this isn't reporting a bug, talking about it in our Discord or Forum would be a better option.