addTilesetImage to map built with images collection

Hello!
I’ve built a map with Tiled with a tileset built from an images collection.
So, I would to know how to load this tileset in my scene?

Here where I am in my code work:

export default class PreloadLevel1 extends Phaser.Scene {

	//...

	preload() {
		for (let i = 1; i < 101; i++) {
			const num = i.toString().padStart(3, '0');
			this.load.image('objects' + num, 'assets/img/tiles/objects' + num + '.png');
			this.load.image('tiles' + num, 'assets/img/tiles/tiles' + num + '.png');
		}
		this.load.tilemapTiledJSON('tileset', 'assets/json/levels/level1.json');
	}

	//...
}


export default class Level1 extends Phaser.Scene {
	
	//...

	create() {
		this.tilemap = this.make.tilemap({ key:'tileset' });

		for (let i = 1; i < 101; i++) {
			const num = i.toString().padStart(3, '0');
			this.tilesets.push(this.tilemap.addTilesetImage('tileset', 'objects' + num));
			this.tilesets.push(this.tilemap.addTilesetImage('tileset', 'tiles' + num));
		}

		//...
	}

	//...
}

But I finish with the warning in my console: No data found for Tileset: tileset

Here an extract of my level1.json file:

"tilesets":[
        {
         "columns":0,
         "firstgid":1,
         "grid":
            {
             "height":1,
             "orientation":"orthogonal",
             "width":1
            },
         "margin":0,
         "name":"tileset",
         "spacing":0,
         "tilecount":173,
         "tileheight":64,

As you can see, the name of my tileset is right.

And another extract of this same file to see you how my tiles array is built:

         "tiles":[
                {
                 "id":404,
                 "image":"..\/..\/img\/tiles\/objects001.png",
                 "imageheight":17,
                 "imagewidth":13
                }, 
                {
                 "id":405,
                 "image":"..\/..\/img\/tiles\/objects002.png",
                 "imageheight":19,
                 "imagewidth":20
                }, 
                {
                 "id":406,
                 "image":"..\/..\/img\/tiles\/objects003.png",
                 "imageheight":35,
                 "imagewidth":22
                }, 
                {
                 "id":407,
                 "image":"..\/..\/img\/tiles\/objects004.png",
                 "imageheight":40,
                 "imagewidth":43
                }, 
                {
                 "id":408,
                 "image":"..\/..\/img\/tiles\/objects005.png",
                 "imageheight":40,
                 "imagewidth":43
                }, 
                {
                 "id":409,
                 "image":"..\/..\/img\/tiles\/objects006.png",
                 "imageheight":40,
                 "imagewidth":35
                }, 

Is somebody to help me?

:wave:

Could you add

console.log('tilesets', this.tilemap.tilesets);

What shows?

Firstly, thanks for the answer :slight_smile:
This is an excellent question!
Here an extract of the TIleset array I’ve got with this log:

[
    {
        "name": "../../img/tiles/objects001.png",
        "firstgid": 405,
        "tileWidth": 96,
        "tileHeight": 64,
        "tileMargin": 0,
        "tileSpacing": 0,
        "tileProperties":
        {},
        "tileData":
        {},
        "image": null,
        "glTexture": null,
        "rows": 1,
        "columns": 1,
        "total": 1,
        "texCoordinates":
        [
            {
                "x": 0,
                "y": 0
            }
        ]
    },
    {
        "name": "../../img/tiles/objects002.png",
        "firstgid": 406,
        "tileWidth": 96,
        "tileHeight": 64,
        "tileMargin": 0,
        "tileSpacing": 0,
        "tileProperties":
        {},
        "tileData":
        {},
        "image": null,
        "glTexture": null,
        "rows": 1,
        "columns": 1,
        "total": 1,
        "texCoordinates":
        [
            {
                "x": 0,
                "y": 0
            }
        ]
    },
    {
        "name": "../../img/tiles/objects003.png",
        "firstgid": 407,
        "tileWidth": 96,
        "tileHeight": 64,
        "tileMargin": 0,
        "tileSpacing": 0,
        "tileProperties":
        {},
        "tileData":
        {},
        "image": null,
        "glTexture": null,
        "rows": 1,
        "columns": 1,
        "total": 1,
        "texCoordinates":
        [
            {
                "x": 0,
                "y": 0
            }
        ]
    },
    {
        "name": "../../img/tiles/objects004.png",
        "firstgid": 408,
        "tileWidth": 96,
        "tileHeight": 64,
        "tileMargin": 0,
        "tileSpacing": 0,
        "tileProperties":
        {},
        "tileData":
        {},
        "image": null,
        "glTexture": null,
        "rows": 1,
        "columns": 1,
        "total": 1,
        "texCoordinates":
        [
            {
                "x": 0,
                "y": 0
            }
        ]
    },
    {
        "name": "../../img/tiles/objects005.png",
        "firstgid": 409,
        "tileWidth": 96,
        "tileHeight": 64,
        "tileMargin": 0,
        "tileSpacing": 0,
        "tileProperties":
        {},
        "tileData":
        {},
        "image": null,
        "glTexture": null,
        "rows": 1,
        "columns": 1,
        "total": 1,
        "texCoordinates":
        [
            {
                "x": 0,
                "y": 0
            }
        ]
    },
    {
        "name": "../../img/tiles/objects006.png",
        "firstgid": 410,
        "tileWidth": 96,
        "tileHeight": 64,
        "tileMargin": 0,
        "tileSpacing": 0,
        "tileProperties":
        {},
        "tileData":
        {},
        "image": null,
        "glTexture": null,
        "rows": 1,
        "columns": 1,
        "total": 1,
        "texCoordinates":
        [
            {
                "x": 0,
                "y": 0
            }
        ]
    },
    {
        "name": "../../img/tiles/objects007.png",
        "firstgid": 411,
        "tileWidth": 96,
        "tileHeight": 64,
        "tileMargin": 0,
        "tileSpacing": 0,
        "tileProperties":
        {},
        "tileData":
        {},
        "image": null,
        "glTexture": null,
        "rows": 1,
        "columns": 1,
        "total": 1,
        "texCoordinates":
        [
            {
                "x": 0,
                "y": 0
            }
        ]
    },

What I see is that the name of each tileset actually is the path of the tile image. And NULL as texture and image. Do not know if it is a clue.

Below the code of my Game, Preload Scene and current Scene.

import 'phaser';
import PreloadLevel1 from './scenes/preloadLevel1';
import Level1 from './scenes/level1';

const DEFAULT_WIDTH = 1280;
const DEFAULT_HEIGHT = 480;

const config = {
	type: Phaser.AUTO,
	backgroundColor: '#ffffff',
	scale: {
		parent: 'phaser-game',
		mode: Phaser.Scale.FIT,
		autoCenter: Phaser.Scale.CENTER_BOTH,
		width: DEFAULT_WIDTH,
		height: DEFAULT_HEIGHT,
	},
	scene: [PreloadLevel1, Level1],
	physics: {
		default: 'arcade',
		arcade: {
			debug: true,
			gravity: { y: 0 },
		},
	},
};

window.addEventListener('load', () => {
	const game = new Phaser.Game(config);
});
import { SceneKey } from './index';
export default class PreloadLevel1 extends Phaser.Scene {
	constructor() {
		super({ key: SceneKey.PreloadLevel1 });
	}

	preload() {
		for (let i = 1; i < 101; i++) {
			const num = i.toString().padStart(3, '0');
			this.load.image('objects' + num, 'assets/img/tiles/objects' + num + '.png');
			this.load.image('tiles' + num, 'assets/img/tiles/tiles' + num + '.png');
		}
		this.load.tilemapTiledJSON('tileset', 'assets/json/levels/level1.json');
		this.load.atlas(
			'player',
			'assets/img/chars/player_atlas.png',
			'assets/json/chars/player_atlas.json',
		);
	}

	create() {
		this.scene.start(SceneKey.Level1);
	}
}
import { SceneKey } from './index';

export default class Level1 extends Phaser.Scene {
	tilemap: Phaser.Tilemaps.Tilemap;
	tilesets: Phaser.Tilemaps.Tileset[] = [];
	bckgLayer: Phaser.Tilemaps.TilemapLayer;
	groundLayer: Phaser.Tilemaps.TilemapLayer;
	wallLayer: Phaser.Tilemaps.TilemapLayer;
	wall2Layer: Phaser.Tilemaps.TilemapLayer;
	desksLayer: Phaser.Tilemaps.TilemapLayer;
	platformsLayer: Phaser.Tilemaps.TilemapLayer;
	dorsLayer: Phaser.Tilemaps.TilemapLayer;
	ceilingLayer: Phaser.Tilemaps.TilemapLayer;
	lightsLayer: Phaser.Tilemaps.TilemapLayer;
	tpLayer: Phaser.Tilemaps.TilemapLayer;

	constructor() {
		super({ key: SceneKey.Level1 });
	}

	create() {
		this.tilemap = this.make.tilemap({ key:'tileset' });

		for (let i = 1; i < 101; i++) {
			const num = i.toString().padStart(3, '0');
			this.tilesets.push(this.tilemap.addTilesetImage('tileset', 'objects' + num));
			this.tilesets.push(this.tilemap.addTilesetImage('tileset', 'tiles' + num));
		}

		this.bckgLayer = this.tilemap.createLayer('background', this.tilesets, 0, 0);
		this.groundLayer = this.tilemap.createLayer('ground', this.tilesets, 0, 0);
		this.wallLayer = this.tilemap.createLayer('wall', this.tilesets, 0, 0);
		this.wall2Layer = this.tilemap.createLayer('wall2', this.tilesets, 0, 0);
		this.desksLayer = this.tilemap.createLayer('desks', this.tilesets, 0, 0);
		this.platformsLayer = this.tilemap.createLayer('platforms', this.tilesets, 0, 0);
		this.dorsLayer = this.tilemap.createLayer('doors', this.tilesets, 0, 0);
		this.ceilingLayer = this.tilemap.createLayer('ceiling', this.tilesets, 0, 0);
		this.lightsLayer = this.tilemap.createLayer('lights', this.tilesets, 0, 0);
		this.tpLayer = this.tilemap.createLayer('tp', this.tilesets, 0, 0);

		console.log('tilesets', this.tilemap.tilesets);
	}
}

It looks like you will do

this.tilemap.addTilesetImage('../../img/tiles/objects001.png', 'objects001');

etc.

Thanks to your help, I am on a beginning of solution :slight_smile:

Firstly, my updated code now looks like:

export default class Level1 extends Phaser.Scene {
	
	//...

	async create() {
		this.tilemap = this.make.tilemap({ key:'tileset' });

		for (let i = 1; i < 101; i++) {
			const num = i.toString().padStart(3, '0');
			this.tilesets.push(this.tilemap.addTilesetImage('../../img/tiles/tiles' + num + '.png', 'tiles' + num));
			this.tilesets.push(this.tilemap.addTilesetImage('../../img/tiles/objects' + num + '.png', 'objects' + num));
		}

		this.bckgLayer = this.tilemap.createLayer('background', this.tilemap.tilesets, 0, 0);
		this.groundLayer = this.tilemap.createLayer('ground', this.tilemap.tilesets, 0, 0);
		this.dorsLayer = this.tilemap.createLayer('doors', this.tilemap.tilesets, 0, 0);
		this.ceilingLayer = this.tilemap.createLayer('ceiling', this.tilemap.tilesets, 0, 0);
	}

	//...
}

But I ended with a white scene and warnings like Image tile area not tile size multiple in: ../../img/tiles/objects090.png

According to answers on the web, I’ve added the size of each image in the addTilesetImage method. But it became a little tricky, because I had to search for each image size by using the json from Tiled.

It begins in the Preload scene:

export default class PreloadLevel1 extends Phaser.Scene {
	//...

	preload() {
		this.load.json('level1', '../../assets/json/levels/level1.json'); // <--- here we put the json in Phaser cache
		for (let i = 1; i < 101; i++) {
			const num = i.toString().padStart(3, '0');
			this.load.image('objects' + num, 'assets/img/tiles/objects' + num + '.png');
			this.load.image('tiles' + num, 'assets/img/tiles/tiles' + num + '.png');
		}
		//...
	}

	//...
}

And the tricky part is in the level scene:

export default class Level1 extends Phaser.Scene {
	
	//...

	async create() {
		this.tilemap = this.make.tilemap({ key:'tileset' });
		// get back the json
		const json = this.cache.json.get('level1');

		// function used below in order to find each image size
		const findTileByName = (name) => json.tilesets[0].tiles.find((tile) => tile.image === name);

		for (let i = 1; i < 101; i++) {
			const num = i.toString().padStart(3, '0');
			const tile = findTileByName('../../img/tiles/tiles' + num + '.png');
			if (tile) {
				const { id: tileId, imageheight: tileHeight, imagewidth: tileWidth } = tile;
				this.tilesets.push(this.tilemap.addTilesetImage('../../img/tiles/tiles' + num + '.png', 'tiles' + num, tileWidth, tileHeight));
			}
			const object = findTileByName('../../img/tiles/objects' + num + '.png');
			if (object) {
				const { id: objectId, imageheight: objectHeight, imagewidth: objectWidth } = object;
				this.tilesets.push(this.tilemap.addTilesetImage('../../img/tiles/objects' + num + '.png', 'objects' + num, objectWidth, objectHeight));
			}
		}

		this.bckgLayer = this.tilemap.createLayer('background', this.tilemap.tilesets, 0, 0);
		this.groundLayer = this.tilemap.createLayer('ground', this.tilemap.tilesets, 0, 0);
		this.dorsLayer = this.tilemap.createLayer('doors', this.tilemap.tilesets, 0, 0);
		this.ceilingLayer = this.tilemap.createLayer('ceiling', this.tilemap.tilesets, 0, 0);
	}

	//...
}

Current result is awfull, tiles appear but are very deformed.

I will continue to dig for a viable solution but maybe I will ended by create real tileset and make it as usual.