Tilemaps - samme/phaser3-faq GitHub Wiki
There is a good tutorial series, Modular Game Worlds in Phaser 3:
- Static Maps — tilesets, map from array, map from CSV, map from Tiled JSON, collisions with Arcade Physics
- Dynamic Platformer — painting tiles, converting tiles to sprites, Arcade Physics hitboxes
- Procedural Dungeon — blank layers, fill tiles, put tiles at
- Meet Matter.js — Matter Physics, convert tilemap layer, collision shapes
Summary
The basic procedure is:
- Load tileset images
- Load a tilemap file, if using one
- Create a tilemap object
- Assign tileset images to the tilemap
- Create tilemap layers, specifying one or more tilesets for each
- Mark colliding tiles in a layer, if you want collisions
- Add a collider for a tile layer, if you want collisions
Tileset images
Every tilemap layer needs at least one tileset image to render. You assign this to the map with addTilesetImage().
load.image() is fine for this, but you can also use load.spritesheet() (with the appropriate frame dimensions) if you want to use the tileset image as a multiframe texture for other game objects like sprites.
If you get any errors loading images, fix those first before creating the tilemap.
Empty tilemap
Tilemap from array
Tilemap from CSV
Tilemap from Tiled
- Tiled JSON map example
- Tiled multiple tilesets example
- Static Maps: Building a Map in Tiled etc.
Create the tilemap from the loaded map data:
const tilemap = this.add.tilemap('map');
If you've forgotten the tile layer or tileset names, you can find them there:
console.log('tile layers', tilemap.layers);
console.log('tilesets', tilemap.tilesets);
For each tileset, add an image:
const tileset = tilemap.addTilesetImage('name', 'textureKey');
For each layer, create a layer with at least one tileset:
const tileLayer = tilemap.createLayer('tileLayerName', tileset);
The lazy way to create tilemap layers:
for (const { name } of tilemap.layers) {
tilemap.createLayer(name, tilemap.tilesets);
}
Collisions with Arcade Physics
collide()
and add.collider()
test only the tile IDs or locations set by setCollision()
etc., setTileIndexCallback()
, and setTileLocationCallback()
. For the last two, your callback can return false
to cancel separation with the tile.
overlap()
and add.overlap()
test all intersecting tiles, including empty tiles. You can filter these out pretty easily if you need to.
this.physics.add.overlap(
sprite,
tilemapLayer,
function onOverlap(sprite, tile) {
console.log("overlap", tile.x, tile.y);
},
function process(sprite, tile) {
// Tile not empty
return tile.index > -1;
}
);
Object layers
Check your object properties
const map = this.add.tilemap(/*…*/);
const [firstObjectLayer] = map.objects;
console.info('Object properties in %s:', firstObjectLayer.name);
console.table(firstObjectLayer.objects);
console.info('Object custom properties in %s:', firstObjectLayer.name);
console.table(firstObjectLayer.objects.map(o => o.properties));
Collision shapes
Performance
- Reduce the number of visible layers
- Reduce the number of visible tiles in the viewport (e.g., don't zoom out)
- Reduce the number of cameras
For small static maps, you can draw map layers onto a Render Texture (maybe 4096 × 4096 at largest) and then hide or destroy the originals.