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

convertTilemapLayer for isometric tilemaps not setting bodies properly #5764

Closed
mayacoda opened this issue Jun 29, 2021 · 5 comments · Fixed by #5767
Closed

convertTilemapLayer for isometric tilemaps not setting bodies properly #5764

mayacoda opened this issue Jun 29, 2021 · 5 comments · Fixed by #5767

Comments

@mayacoda
Copy link
Contributor

mayacoda commented Jun 29, 2021

Version

  • Phaser Version: 3.55.2
  • Operating system: macOS
  • Browser:

Description

I'm having an issue with setting up collisions with a staggered isometric tilemap created in Tiled. I ran across this discussion outlining the same issue, and I can confirm it's still a problem in 3.55.2. Basically, convertTilemapLayer does not set the collision bodies for tiles correctly on isometric maps, neither the default rectangle nor the shape specified in the collision layer.

As suggested in the thread, the issue comes from getBounds() on the Tile class. Specifically, this.getLeft() always returns undefined for any of the tiles.

    getBounds: function (camera, output)
    {
        if (output === undefined) { output = new Rectangle(); }

        output.x = this.getLeft();
        output.y = this.getTop();
        output.width = this.getRight() - output.x;
        output.height = this.getBottom() - output.y;

        return output;
    }

Example Test Code

    const map = this.make.tilemap({ key: 'map' })
    const tileset = map.addTilesetImage('tileset', 'tiles')
    const ground = map.createLayer('Floor', tileset)

    // property "collides" is set on certain tiles within Tiled
    ground.setCollisionByProperty({ collides: true })

    this.matter.world.convertTilemapLayer(ground)

Additional Information

I'm happy to give solving this a shot myself if you could provide some guidance. 🙂

@mayacoda
Copy link
Contributor Author

I found the root of the problem. When Tile.getLeft is called, it calls ultimately calls GetTileToWorldXFunction which currently doesn't support any other kind of projection besides orthogonal.

var GetTileToWorldXFunction = function (orientation)
{
    if (orientation === CONST.ORTHOGONAL)
    {
        return TileToWorldX;
    }
    else
    {
        return NOOP;
    }
};

I'm tempted to add a StaggeredTileToWorldX function, but I see that in line src/tilemaps/components/StaggeredTileToWorldXY.js:49, the tileY parameter is necessary for computing the x value of the tile.

Would it be a usable alternative to get both the x and y components in getBounds() from the GetTileToWorldXYFunction?

@photonstorm
Copy link
Collaborator

This issue has been mentioned on Phaser. There might be relevant details there:

https://phaser.discourse.group/t/phaser-isometric-tiled-map-collisions/9092/9

@mayacoda
Copy link
Contributor Author

This issue has been mentioned on Phaser. There might be relevant details there:

https://phaser.discourse.group/t/phaser-isometric-tiled-map-collisions/9092/9

Actually, that was me. I figured I'd give whomever was invested in the bug that a fix was being worked on.

@photonstorm
Copy link
Collaborator

This issue has been mentioned on Phaser. There might be relevant details there:

https://phaser.discourse.group/t/arcade-physics-collisions-with-isometric-tilemap/10050/1

@photonstorm
Copy link
Collaborator

Thanks for opening this issue, and for submitting a PR to fix it. We have merged your PR into the master branch and attributed the work to you in the Change Log. If you need to tweak the code for whatever reason please submit a new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants