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.22k stars 7.1k forks source link

`putTileAt` into `createBlankLayer` on hex map from Tiled renders wrong #6074

Open wwoods opened 2 years ago

wwoods commented 2 years ago

Version

Description

See below image; base map is colored hex squares. If I dynamically add a layer via createBlankLayer, and then use putTileAt to populate this layer, the result is off-centered rendering of the tiles in the blank layer:

image

Example Test Code

// Preload
this.load.image('tiles', assetHexMini);
this.load.tilemapTiledJSON('map', assetHexMap);

// Create
const map = this.make.tilemap({key: 'map'});
const tileset = map.addTilesetImage('hexmini-6x', 'tiles');
const platforms = map.createLayer('Ground', tileset);

// Now, as a UI layer, circle two tiles using tile ID 2
const uiLayer = map.createBlankLayer('beep', tileset);
uiLayer.putTileAt(2, 2, 2);
uiLayer.putTileAt(2, 3, 2);

The map: hexagonal-mini-6x.json.tar.gz

The tileset image: hexmini-6x

Additional Information

This issue was worse with 3.55; I found some bugs which were fixed regarding putTileAt, hence tried the 3.60 beta.

wwoods commented 2 years ago

Workaround: (see bottom for real workaround)

const uiLayer = map.createBlankLayer('beep', tileset,
    // Until https://github.com/photonstorm/phaser/issues/6074 is fixed
    0, platforms.layer.tileHeight * 0.5);

Nevermind, if I try to highlight every tile, it's clear that the vertical distances are half what they should be:

for (const t of platforms.getTilesWithin()) {
  if (t.index < 0) continue;
  uiLayer.putTileAt(2, t.x, t.y);
}

image

Possible cause?

It looks like uiLayer.layer.hexSideLength is not being set correctly. It starts at zero. If I run the following code immediately after allocating uiLayer, the printed positions match, but this does not appear to affect the subsequently placed tiles:

uiLayer.layer.hexSideLength = platforms.layer.hexSideLength; // commenting this prints 2 different numbers.
console.log(platforms.tileToWorldXY(2, 2));
console.log(uiLayer.tileToWorldXY(2, 2));

Actual workaround

Ok, it is the hexSideLength issue. Can fix as follows:

const uiLayer = map.createBlankLayer('beep', tileset);
// Until https://github.com/photonstorm/phaser/issues/6074 is fixed
uiLayer.layer.hexSideLength = platforms.layer.hexSideLength;
for (const t of uiLayer.getTilesWithin()) {
  t.updatePixelXY();
}
// End fix

// All locations now render correctly
uiLayer.putTileAt(2, 2, 3);
klm127 commented 3 days ago

In my case, with North/South hexes, I also had to set staggerAxis to "x" before updating pixelXY. Thanks for the workaround re: updatePixelXY.