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

Enabling Light2D pipeline incorrectly shifts sprite, only if x or y position is odd #6698

Open
PaulB-H opened this issue Dec 27, 2023 · 0 comments
Assignees
Milestone

Comments

@PaulB-H
Copy link

PaulB-H commented Dec 27, 2023

Version

  • Phaser Version:
    3.70.0 (WebGL | Web Audio)

  • Operating system:
    Windows 10 Home 64-bit (10.0, build 19045)

  • Browser:
    Firefox: 121.0 (64-bit)
    Chrome 120.0.6099.130 (Official Build) (64-bit)

Description

When enabling Light2D pipeline, sprites are shifted incorrectly ONLY if the x or y location is odd.

After enabling the pipeline on an odd x/y block, while the position of the sprite becomes visually incorrect, the reported coordinates are still correct.

This was not resolved by trying roundPixels: false;

I used a non-extruded tile-set to ensure that was not related.

Tileset is 16x16px tiles on a 10x10 sheet
The map is 160 x 240
Using scale: mode: Phaser.Scale.FIT

Example Test Code

Live Example:

https://paulbh.com/phaserbug

Repo:

https://github.com/PaulB-H/phaser-position-bug

Assets:

tileset image & normal map:
breakout-assets.png, breakout-assets_n.png

tiled tileset:
breakout-tileset.tsx

Yellow blocks have the light2d pipeline disabled.
Blue block have it enabled.

If we look in our map file, position_test.json, we can see our block positions:

Yellow
x: 32, y: 80
Yellow
x: 97, y: 81

Blue
x: 32, y: 144
Blue
x: 97, y: 145

Blue
x: 32, y: 208
Blue
x: 97, y: 209

In utility/parseMap.ts we can see the code that actually parses the map from tiled. I am using setOrigin(0, 1) to position the sprite correctly, but I also tried manually doing the alignment with no change.

export const parseMap = (scene: Phaser.Scene, map: Phaser.Tilemaps.Tilemap) => {
  const blocksLayer = map.getObjectLayer("blocks");
  const wallsLayer = map.getObjectLayer("walls");

  blocksLayer.objects.forEach((block) => {
  
    const newBlock = block as iBlock;
  
    const blockSprite = scene.physics.add.sprite(
      newBlock.x,
      newBlock.y,
      SHEETS.Tiles,
      newBlock.gid - 1
    ) as iBlockSprite;
  
    blockSprite.setOrigin(0, 1);
  
    blockSprite.setPipeline("Light2D");
  };
};

We are also drawing debug rects using the coords from the blocks, which are positioned correctly.

//////  Debug Graphics
if (debugBlocks) {
  const rectX = block.x!;
  const rectY = block.y! - block.height!;
  const rectWidth = block.height!;
  const rectHeight = block.height!;

  const graphics = scene.add.graphics();

  graphics.fillStyle(0xff0000);

  graphics.fillRect(rectX, rectY, rectWidth, rectHeight).setDepth(0);
}

Additional Information

In the below image, left blocks are at even x/y coordinates, and the right blocks have their position shifted right and down by 1 pixel

Only the right blue blocks, which have odd x/y coordinates AND the Light2D pipeline are affected.

We can also note the overflow / sizing issue is not consistent between them, the right middle block seems stretched vertically a bit and too far right, whereas the bottom right block seems shifted down and to the right.

Trying to detect and subtract from the positioning when detecting an odd number does not work either, the overflow just moves to the opposite side, its as if its been moved half a pixel after enabling Light2D.

image

I think this is a bug because the positioning issue does not happen if the Light2D pipeline is disabled, however we can also see the top right yellow block (odd x/y coordinates, but no Light2D) does appear slightly stretched, but the position is correct.

I do also think it could have something to do with using power of 2 for the map size, so perhaps there is something fundamental about how scaling and map size works that I don't understand.


Update:

I have seen some other comments about this setting so I added it, but it did not resolve the issue:

this.game.scale.displaySize.setSnap(160, 240);
this.game.scale.refresh();
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

4 participants