Claude
Skills
Sign in
Back

tilemaps

Included with Lifetime
$97 forever

Use this skill when working with tilemaps in Phaser 4. Covers loading Tiled JSON maps, creating tilemap layers, tile collision, dynamic tiles, tile properties, and tilemap camera culling. Triggers on: Tilemap, Tiled, tilemap layer, tile collision, tile properties.

General

What this skill does


# Tilemaps
> Phaser Tilemaps render tile-based levels from Tiled JSON, CSV, or raw 2D arrays. A `Tilemap` holds parsed map data and provides methods to add tilesets, create layers, set collision, and query tiles. Layers (`TilemapLayer` or `TilemapGPULayer`) are the Game Objects that actually render tiles. Phaser supports orthogonal, isometric, hexagonal, and staggered maps.

**Key source paths:** `src/tilemaps/Tilemap.js`, `src/tilemaps/TilemapLayer.js`, `src/tilemaps/TilemapGPULayer.js`, `src/tilemaps/TilemapLayerBase.js`, `src/tilemaps/Tile.js`, `src/tilemaps/Tileset.js`, `src/tilemaps/TilemapFactory.js`, `src/tilemaps/components/`, `src/tilemaps/parsers/tiled/`
**Related skills:** ../loading-assets/SKILL.md, ../sprites-and-images/SKILL.md

## Quick Start

```js
class GameScene extends Phaser.Scene {
    preload() {
        // Load the Tiled JSON and the tileset image
        this.load.tilemapTiledJSON('map', 'assets/level1.json');
        this.load.image('tiles', 'assets/tilesheet.png');
    }

    create() {
        // Create the tilemap from cached JSON
        const map = this.add.tilemap('map');

        // Link the tileset image to the tileset name used in Tiled
        const tileset = map.addTilesetImage('tilesheet', 'tiles');

        // Create a layer - layerID must match the layer name in Tiled
        const ground = map.createLayer('Ground', tileset);

        // Enable collision on specific tile indexes
        ground.setCollision([1, 2, 3]);
    }
}
```

The flow is always: load JSON + image, create tilemap, add tileset image, create layer(s), set collision.

## Core Concepts

### Tilemap vs Layer

A `Tilemap` is a data container, not a display object. It stores parsed map data (layers, tilesets, objects) and provides methods that operate on them. A `TilemapLayer` or `TilemapGPULayer` is the actual Game Object added to the display list that renders tiles.

```js
const map = this.add.tilemap('map');    // Data container (not rendered)
const layer = map.createLayer('Ground', tileset);  // Game Object (rendered)
```

`this.add.tilemap(key)` is a factory registered on `GameObjectFactory`. It delegates to `ParseToTilemap` which reads from the cache and returns a `Tilemap` instance.

### Tilesets

A `Tileset` (`src/tilemaps/Tileset.js`) links a tileset name (from Tiled) to a loaded texture. It stores `firstgid`, tile dimensions, margin, and spacing.

```js
// tilesetName: the name in Tiled's tileset panel
// key: the Phaser texture key (defaults to tilesetName if omitted)
const tileset = map.addTilesetImage('tilesetName', 'textureKey');

// Override tile dimensions, margin, and spacing if needed
const tileset = map.addTilesetImage('name', 'key', 16, 16, 1, 2);
```

`addTilesetImage(tilesetName, key, tileWidth, tileHeight, tileMargin, tileSpacing, gid, tileOffset)` - If the tileset name already exists in the parsed map data, it updates the existing Tileset object with the texture. If not (non-Tiled maps), it creates a new Tileset.

**Important:** The Phaser Tiled parser does not support "Collection of Images" tilesets. All tiles must be in a single tileset image per tileset.

### The Tile Class

Each cell in a layer is a `Tile` object (`src/tilemaps/Tile.js`). Key properties:

- `index` - tile index in the tileset (-1 for empty)
- `x`, `y` - tile coordinates (in tiles, not pixels)
- `pixelX`, `pixelY` - pixel position relative to layer origin
- `width`, `height` - tile size in pixels
- `properties` - custom properties from Tiled (object)
- `collideLeft`, `collideRight`, `collideUp`, `collideDown` - per-edge collision flags
- `faceLeft`, `faceRight`, `faceTop`, `faceBottom` - interesting face flags for collision optimization
- `collisionCallback` - per-tile collision callback function
- `tint` - tint color value (default `0xffffff`)
- `tintMode` - tint blend mode (default `TintModes.MULTIPLY`)
- `rotation` - rotation angle
- `physics` - object for physics-engine-specific data (e.g. bodies)
- `alpha`, `visible`, `flipX`, `flipY` - inherited from mixins

### TilemapGPULayer (v4.0.0)

`TilemapGPULayer` is a high-performance WebGL-only alternative to `TilemapLayer`. It renders the entire layer as a single quad using a shader, making it almost entirely GPU-bound.

```js
// Pass gpu: true as the 5th argument to createLayer
const layer = map.createLayer('Ground', tileset, 0, 0, true);
```

**Capabilities:**
- Single tileset per layer only (no multi-tileset)
- Max tilemap size: 4096x4096 tiles
- Max unique tile IDs: 2^23 (8,388,608)
- Supports tile flip and tile animation
- Orthographic maps only (no iso/hex/staggered)
- Smooth tile borders with LINEAR filtering (no seams)
- Sharp pixels with NEAREST filtering

**Restrictions:**
- Layer edits do not display automatically. Call `generateLayerDataTexture()` after modifying tiles.
- WebGL renderer only (no Canvas fallback)
- Cannot use multiple tilesets on a single layer

```js
// If you edit tiles on a GPU layer, regenerate the data texture:
gpuLayer.putTileAt(5, 10, 10);
gpuLayer.generateLayerDataTexture();
```

### TilemapLayerBase

Both `TilemapLayer` and `TilemapGPULayer` extend `TilemapLayerBase` (`src/tilemaps/TilemapLayerBase.js`), which extends `GameObject`. The base class provides all tile query, manipulation, and collision methods. It includes these component mixins: Alpha, BlendMode, ComputedSize, Depth, ElapseTimer, Flip, GetBounds, Lighting, Mask, Origin, RenderNodes, Transform, Visible, ScrollFactor, and Arcade Physics Collision.

## Common Patterns

### Creating from Tiled JSON

```js
preload() {
    this.load.tilemapTiledJSON('map', 'assets/map.json');
    this.load.image('tiles', 'assets/tileset.png');
}

create() {
    const map = this.add.tilemap('map');
    const tileset = map.addTilesetImage('TilesetNameInTiled', 'tiles');
    const layer = map.createLayer('LayerNameInTiled', tileset);
}
```

The `layerID` passed to `createLayer` must match the layer name in Tiled exactly. Group layer children are flattened with a `'ParentGroup/Layer'` naming convention.

### Multiple Layers

```js
const map = this.add.tilemap('map');
const tileset = map.addTilesetImage('terrain', 'terrain-img');

const background = map.createLayer('Background', tileset);
const ground = map.createLayer('Ground', tileset);
const foreground = map.createLayer('Foreground', tileset);

// Layers are rendered in creation order. Use depth for finer control:
foreground.setDepth(10);
```

A layer can use multiple tilesets (CPU layer only):

```js
const tiles1 = map.addTilesetImage('terrain', 'terrain-img');
const tiles2 = map.addTilesetImage('objects', 'objects-img');
const layer = map.createLayer('Ground', [tiles1, tiles2]);
```

### Creating a Blank Layer

```js
const map = this.add.tilemap('map');
const tileset = map.addTilesetImage('terrain', 'terrain-img');

// createBlankLayer(name, tileset, x, y, width, height, tileWidth, tileHeight)
const layer = map.createBlankLayer('dynamic', tileset, 0, 0, 50, 50, 32, 32);

// Fill it with tiles
layer.fill(1);  // Fill entire layer with tile index 1
layer.putTileAt(5, 10, 10);  // Place tile index 5 at tile coord (10, 10)
```

### Collision Setup

There are several ways to enable tile collision for Arcade Physics:

```js
// By specific tile indexes
layer.setCollision([1, 2, 3]);

// By range (inclusive)
layer.setCollisionBetween(1, 50);

// By tile property (set in Tiled's tileset editor)
layer.setCollisionByProperty({ collides: true });
// Supports arrays: { type: ['stone', 'lava'] }

// By exclusion - collide on ALL tiles except these
layer.setCollisionByExclusion([-1, 0]);  // -1 is empty, 0 is often background

// From Tiled collision editor shapes
layer.setCollisionFromCollisionGroup();
```

All collision methods on `TilemapLayerBase` mirror methods on `Tilemap` but don't require a `layer` parameter. On the `Tilemap`, you can pass a layer reference or use the "current layer":

```js
map.setLayer('Ground');
map.setCollision([1, 2, 3]);  // Applies to current layer
// Or spe
Files: 1
Size: 19.1 KB
Complexity: 24/100
Category: General

Related in General