Skip to content

Phaser Tilemaps Advanced — Multi-Layer and Dynamic Maps

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Phaser Tilemaps Advanced. We cover key concepts, practical examples, and best practices to help you master this topic.

Phaser advanced tilemaps support multi-layer maps, per-tile collision, dynamic tile swapping, animated tiles, and efficient rendering of large maps.

What You'll Learn

By the end of this guide, you will create multi-layer tilemaps, set collision on specific tile indices, swap tiles dynamically for destruction, create animated tiles, use tile properties for game logic, and optimize large map performance.

Multi-Layer Tilemap

var map = this.make.tilemap({ key: 'map' });
var groundLayer = map.addLayer('ground');
var decorLayer = map.addLayer('decor');
var collisionLayer = map.addLayer('collision');

collisionLayer.setCollisionByProperty({ collides: true });

Dynamic Tile Swap

function breakTile(tile) {
    if (tile) {
        mapLayer.removeTileAt(tile.x, tile.y);
        // Or swap to a broken tile
        mapLayer.putTileAt(5, tile.x, tile.y);
    }
}

Animated Tiles

// Create animation for tile index 3
this.anims.create({
    key: 'waterAnim',
    frames: [3, 8, 13],
    frameRate: 4,
    repeat: -1
});

// In update, swap tile frame based on time
// (Phaser does not natively animate tiles; update in ticker)

Tile Properties

// In Tiled editor, add custom properties to tiles
var tile = layer.getTileAt(5, 3);
console.log(tile.properties.damage); // Custom property

Common Mistakes

1. Tile Size Mismatch

Map tile size must match the tileset tile size. Mismatch causes rendering gaps.

2. Collision Not Applied

layer.setCollisionByExclusion or setCollisionByProperty must be called after adding the layer.

3. Removing Tiles Destroys Collision

removeTileAt removes the tile and its collision. Check tile existence before operations.

4. Large Maps Performance

Maps over 100x100 tiles can lag. Use chunked rendering or limit visible layers.

5. JSON Map Format

Phaser uses the Tiled JSON format. CSV format is not supported for multi-layer maps.

Practice Questions

Q1: How do you make a multi-layer tilemap? A: Add each layer separately with map.addLayer('layerName').

Q2: How do you set collision on tiles? A: Call layer.setCollisionByProperty({ collides: true }) or setCollisionByExclusion.

Q3: How do you remove a tile dynamically? A: Call layer.removeTileAt(x, y).

Q4: How do you swap a tile? A: Call layer.putTileAt(newIndex, x, y).

Q5: How do you read tile properties? A: Access tile.properties after getting the tile with layer.getTileAt.

Challenge: Build a destructible terrain where clicking on a tile destroys it and surrounding tiles cascade with a delay, like a crumbling wall.

FAQ

Can I use CSV tilemaps?

Phaser prefers JSON format from Tiled. CSV works for single-layer maps.

How do I create tilemaps in code?

Generate an array and pass to map.putTilesAt(array, x, y).

Can tiles have physics bodies?

Yes. Use layer.setCollisionByExclusion to enable physics on tiles.

How do I get tile coordinates from pointer?

Use layer.getTileAtWorldXY(pointer.x, pointer.y).

Can I use tilemaps without Tiled?

Yes. Generate 2D arrays and use map.putTilesAt.

Try It Yourself

Create a tilemap with collision.

<!DOCTYPE html>
<html>
<head>
    <title>Phaser Tilemaps</title>
    <script src="https://cdn.jsdelivr.net/npm/phaser@3/dist/phaser.min.js"></script>
</head>
<body style="font-family:sans-serif;padding:20px;">
<h2>Tilemap Demo</h2>
<script>
var config = {
    type: Phaser.AUTO,
    width: 400,
    height: 400,
    backgroundColor: '#1a1a2e',
    physics: { default: 'arcade', arcade: { gravity: { y: 0 } } },
    scene: {
        create: function() {
            // Create a simple tilemap from arrays
            var mapData = [
                [1, 1, 1, 1, 1, 1, 1, 1],
                [1, 0, 0, 0, 0, 0, 0, 1],
                [1, 0, 0, 0, 0, 0, 0, 1],
                [1, 0, 0, 2, 2, 0, 0, 1],
                [1, 0, 0, 2, 2, 0, 0, 1],
                [1, 0, 0, 0, 0, 0, 0, 1],
                [1, 0, 0, 0, 0, 0, 0, 1],
                [1, 1, 1, 1, 1, 1, 1, 1]
            ];

            // Generate tile texture
            var g = this.make.graphics({ add: false });
            g.fillStyle(0x4ecdc4);
            g.fillRect(0, 0, 48, 48);
            g.fillStyle(0xffffff);
            g.fillRect(1, 1, 46, 46);
            g.generateTexture('tile1', 48, 48);
            g.clear();

            g.fillStyle(0xff6b35);
            g.fillRect(0, 0, 48, 48);
            g.generateTexture('tile2', 48, 48);
            g.destroy();

            // Create tilemap
            var map = this.make.tilemap({ data: mapData, tileWidth: 48, tileHeight: 48 });
            var tileset = map.addTilesetImage('tileset', 'tile1', 48, 48, 0, 0);
            var layer = map.createLayer(0, tileset, 0, 0);

            // Set collision on tile index 1 (walls)
            layer.setCollision(1);

            // Player
            this.player = this.add.circle(72, 72, 12, 0xffffff);
            this.physics.add.existing(this.player);
            this.player.body.setCollideWorldBounds(false);

            this.physics.add.collider(this.player, layer);

            this.cursors = this.input.keyboard.createCursorKeys();
        },
        update: function() {
            var speed = 150;
            this.player.body.setVelocity(0);

            if (this.cursors.left.isDown) this.player.body.setVelocityX(-speed);
            if (this.cursors.right.isDown) this.player.body.setVelocityX(speed);
            if (this.cursors.up.isDown) this.player.body.setVelocityY(-speed);
            if (this.cursors.down.isDown) this.player.body.setVelocityY(speed);
        }
    }
};

var game = new Phaser.Game(config);
</script>
</body>
</html>

What's Next

Add audio.

Audio — Sound and music. Arcade Physics — Arcade physics.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro