phaser
phaser copied to clipboard
Phaser not drawing tilesets of multiple sizes correctly as reflected in tiled.
The tilemap size is 32x32 and the ninja is a 32x64 sprite (imported in tiled as 32x64 also). In tiled I place it on the bottom left but when rendered in phaser, it is an index off.
mappy.json
{ "height":5,
"infinite":false,
"layers":[
{
"data":[17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17],
"height":5,
"id":3,
"name":"Tile Layer 1",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":5,
"x":0,
"y":0
},
{
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0],
"height":5,
"id":4,
"name":"Tile Layer 2",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":5,
"x":0,
"y":0
}],
"nextlayerid":5,
"nextobjectid":1,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.2.1",
"tileheight":32,
"tilesets":[
{
"columns":15,
"firstgid":1,
"image":"..\/..\/32x32Tileset_gardenTheme.png",
"imageheight":480,
"imagewidth":480,
"margin":0,
"name":"32x32Tileset_gardenTheme",
"spacing":0,
"tilecount":225,
"tileheight":32,
"tilewidth":32
},
{
"columns":1,
"firstgid":226,
"image":"..\/..\/32x64.png",
"imageheight":64,
"imagewidth":32,
"margin":0,
"name":"32x64",
"spacing":0,
"tilecount":1,
"tileheight":64,
"tilewidth":32
}],
"tilewidth":32,
"type":"map",
"version":1.2,
"width":5
}
//code
class PlayScene extends Phaser.Scene {
constructor(){
super({key: "PlayScene"});
}
preload(){
this.load.image("set32x32", "./32x32Tileset_gardenTheme.png");
this.load.image("ninja32x64", "./32x64.png");
this.load.tilemapTiledJSON("mappy", "./mappy.json");
}
create(){
let mappy = this.make.tilemap({
key: "mappy"
});
let tilesets = [
mappy.addTilesetImage("32x32Tileset_gardenTheme", "set32x32", 32,32),
mappy.addTilesetImage("32x64", "ninja32x64", 32, 64)
]
mappy.layers.map((value)=>{
mappy.createStaticLayer(value.name, tilesets).setScale(2);
})
}
}
Hey, I have a workaround in our project to fix this issue, we use Isometric and our tiles are oversized (256 * 192 compare to tile size 256 * 128) Note that the position of rotated tile is still a bit off because I have no idea where the anchor point of the tile image is in Tiled. So I chose (0.5, 0.5) as anchor point.
replace pipeline.batchTexture() in Phaser.Tilemaps.TilemapLayer.prototype.renderWebGL with:
pipeline.batchTexture(
src, //gameObject
texture, //texture
texture.width, texture.height, //textureWidth, textureHeight
// x + ((tw + tile.pixelX) * sx), y + ((th + tile.pixelY) * sy),
tile.pixelX + 0.5 * tile.baseWidth, tile.pixelY - (tile.height * 0.5 - tile.baseHeight),
tile.width, tile.height, // srcWidth, srcHeight,
sx, sy, //scaleX, scaleY,
tile.rotation, //rotation
tile.flipX, tile.flipY, //flipX, flipY,
scrollFactorX, scrollFactorY, //scrollFactorX, scrollFactorY,
// tw, th, //displayOriginX, displayOriginY,
tile.width * 0.5, tile.height * 0.5,
frameX, frameY, frameWidth, frameHeight, // frameX, frameY, frameWidth, frameHeight,
tint, tint, tint, tint, false, //tintTL, tintTR, tintBL, tintBR, tintEffect,
0, 0, //uOffset, vOffset,
camera, //camera
null, //parentTransformMatrix
true, //skipFlip
textureUnit //textureUnit
);
It seems most of the time the tiles should be aligned to bottom-left by default - I think its pretty common to have tiles of variable height where baseline always will be the bottom. Possibly an option to provide top alignment.
Interesting to know how others are dealing with this as it seems very common.