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:

  1. Load tileset images
  2. Load a tilemap file, if using one
  3. Create a tilemap object
  4. Assign tileset images to the tilemap
  5. Create tilemap layers, specifying one or more tilesets for each
  6. Mark colliding tiles in a layer, if you want collisions
  7. 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

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.