옵션
집 Skill 기타 tilemaps

Phaser 4에서 타일맵을 다룰 때 이 스킬을 활용하세요. Tiled JSON 맵 불러오기, 타일맵 레이어 생성, 타일 충돌, 동적 타일, 타일 속성, 타일맵 카메라 컬링 등을 다룹니다. 트리거 대상: 타일맵, Tiled, 타일맵 레이어, 타일 충돌, 타일 속성.

...모든 것을 확장하십시오
78
업데이트 된 시간 2026년 8월 4일

Tilemaps

PhaserTilemaps는 Tiled JSON, CSV 또는 원시 2D 배열에서 타일 기반 레벨을 렌더링합니다. A Tilemap 는 파싱된 맵 데이터를 보관하며, 타일셋 추가, 레이어 생성, 충돌 설정 및 타일 조회를 위한 메서드를 제공합니다. 레이어(TilemapLayer 또는 TilemapGPULayer)는 실제로 타일을 렌더링하는 게임 오브젝트입니다. Phaser는 직교, 등각, 육각형 및 엇갈린 맵을 지원합니다.

주요 소스 경로: 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/ 관련 기술: ../loading-assets/SKILL.md, ../sprites-and-images/SKILL.md

빠른 시작

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]);
    }
}

작업 흐름은 항상 다음과 같습니다: JSON + 이미지 불러오기, 타일맵 생성, 타일셋 이미지 추가, 레이어 생성, 충돌 설정.

핵심 개념

타일맵 대 레이어

A Tilemap 는 표시 객체가 아닌 데이터 컨테이너입니다. 파싱된 맵 데이터(레이어, 타일셋, 오브젝트)를 저장하며, 이를 조작하는 메서드를 제공합니다. A TilemapLayer 또는 TilemapGPULayer 는 타일을 렌더링하기 위해 디스플레이 리스트에 추가되는 실제 게임 오브젝트입니다.

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

this.add.tilemap(key)GameObjectFactory에 등록된 팩토리입니다. 이 팩토리는 ParseToTilemap 를 위임하며, 이 메서드는 캐시에서 데이터를 읽어와 Tilemap 인스턴스를 반환합니다.

타일셋

A Tileset (src/tilemaps/Tileset.js)는 (Tiled의) 타일셋 이름을 로드된 텍스처에 연결합니다. 이 객체는 firstgid, 타일 크기, 여백 및 간격을 저장합니다.

// 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) - 파싱된 맵 데이터에 해당 타일셋 이름이 이미 존재하는 경우, 기존 타일셋 객체를 해당 텍스처로 업데이트합니다. 그렇지 않은 경우(Tiled가 아닌 맵), 새로운 타일셋을 생성합니다.

중요: Phaser Tiled 파서는 “이미지 모음(Collection of Images)” 타일셋을 지원하지 않습니다. 모든 타일은 타일셋당 하나의 타일셋 이미지에 포함되어야 합니다.

Tile 클래스

레이어의 각 셀은 Tile 객체(src/tilemaps/Tile.js)입니다. 주요 속성:

  • index - 타일셋 내 타일 인덱스(비어 있는 경우 -1)
  • x, y - 타일 좌표 (픽셀이 아닌 타일 단위)
  • pixelX, pixelY - 레이어 원점을 기준으로 한 픽셀 위치
  • width, height - 픽셀 단위의 타일 크기
  • properties - Tiled(객체)의 사용자 정의 속성
  • collideLeft, collideRight, collideUp, collideDown - 모서리별 충돌 플래그
  • faceLeft, faceRight, faceTop, faceBottom - 충돌 최적화를 위한 관심 면 플래그
  • collisionCallback - 타일별 충돌 콜백 함수
  • tint - 색조 값 (기본값 0xffffff)
  • tintMode - 틴트 블렌드 모드 (기본값 TintModes.MULTIPLY)
  • rotation - 회전 각도
  • physics - 물리 엔진 전용 데이터(예: 바디)를 위한 객체
  • alpha, visible, flipX, flipY - 믹신에서 상속됨

TilemapGPULayer (v4.0.0)

TilemapGPULayer 는 다음의 고성능 WebGL 전용 대안입니다 TilemapLayer. 셰이더를 사용하여 전체 레이어를 단일 쿼드로 렌더링하므로, 거의 전적으로 GPU에 의존합니다.

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

기능:

  • 레이어당 단일 타일셋만 지원 (다중 타일셋 미지원)
  • 최대 타일맵 크기: 4096x4096 타일
  • 최대 고유 타일 ID: 2^23 (8,388,608)
  • 타일 뒤집기 및 타일 애니메이션 지원
  • 정투영 맵만 지원 (이소메트릭/육각형/엇갈린 배열 미지원)
  • LINEAR 필터링을 통한 매끄러운 타일 경계 (이음새 없음)
  • NEAREST 필터링을 통한 선명한 픽셀

제한 사항:

  • 레이어 편집 내용이 자동으로 표시되지 않습니다. 타일을 수정한 후 generateLayerDataTexture() 타일을 수정한 후 호출하십시오.
  • WebGL 렌더러 전용 (Canvas 대체 기능 없음)
  • 단일 레이어에서 여러 타일셋을 사용할 수 없음
// If you edit tiles on a GPU layer, regenerate the data texture:
gpuLayer.putTileAt(5, 10, 10);
gpuLayer.generateLayerDataTexture();

TilemapLayerBase

두 가지 모두 TilemapLayerTilemapGPULayer 상속 TilemapLayerBase (src/tilemaps/TilemapLayerBase.js)를 상속하며, 이는 GameObject를 상속받습니다. 이 기본 클래스는 모든 타일 쿼리, 조작 및 충돌 메서드를 제공합니다. 여기에는 Alpha, BlendMode, ComputedSize, Depth, ElapseTimer, Flip, GetBounds, Lighting, Mask, Origin, RenderNodes, Transform, Visible, ScrollFactor 및 Arcade Physics Collision과 같은 컴포넌트 믹신이 포함됩니다.

일반적인 패턴

Tiled JSON을 활용한 생성

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);
}

전달된 layerID 로 전달된 createLayer 는 Tiled의 레이어 이름과 정확히 일치해야 합니다. 그룹 레이어의 자식 요소들은 'ParentGroup/Layer' 명명 규칙에 따라 평면화됩니다.

여러 레이어

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);

한 레이어에서 여러 타일셋을 사용할 수 있습니다(CPU 레이어에만 해당):

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

빈 레이어 생성

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)

충돌 설정

Arcade Physics에서 타일 충돌을 활성화하는 방법에는 여러 가지가 있습니다:

// 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();

' TilemapLayerBase 미러 메서드 Tilemap 하지만 layer 매개변수가 필요하지 않습니다. Tilemap에서는 레이어 참조를 전달하거나 "현재 레이어"를 사용할 수 있습니다:

map.setLayer('Ground');
map.setCollision([1, 2, 3]);  // Applies to current layer
// Or specify a layer explicitly:
map.setCollision([1, 2, 3], true, true, 'Ground');

물리 통합 (아케이드)

// Enable collisions between a sprite and a tilemap layer
this.physics.add.collider(player, groundLayer);// With a callback
this.physics.add.collider(player, groundLayer, (sprite, tile) => {
    if (tile.index === 5) {
        // Hit a special tile
    }
});// Overlap detection instead of collision
this.physics.add.overlap(player, groundLayer, (sprite, tile) => {
    // Player is overlapping this tile
});

레이어의 타일에는 물리 충돌 감지를 위해 ( setCollision* 메서드를 통해) 설정되어 있어야 물리 엔진이 이를 감지할 수 있습니다. 레이어 자체에는 collisionCategorycollisionMask 속성을 통해 충돌 필터링이 가능합니다.

타일 속성

타일에는 Tiled의 타일셋 편집기에서 사용자 정의 속성을 설정할 수 있습니다:

// Access tile properties
const tile = layer.getTileAt(10, 5);
console.log(tile.properties.damage);    // Custom property from Tiled
console.log(tile.properties.type);      // Custom property from Tiled// Set collision based on custom properties
layer.setCollisionByProperty({ collides: true });
layer.setCollisionByProperty({ type: ['wall', 'rock'] });

타일 콜백

// Callback by tile index - fires when physics body overlaps these tiles
map.setTileIndexCallback([5, 6, 7], (sprite, tile) => {
    // Called for tiles with index 5, 6, or 7
    console.log('Hit tile', tile.index, 'at', tile.x, tile.y);
}, this);// Callback by tile location - fires for tiles in a rectangular area
map.setTileLocationCallback(10, 10, 5, 5, (sprite, tile) => {
    // Called for any tile in the 5x5 region starting at (10, 10)
}, this);// Per-tile callback
const tile = layer.getTileAt(10, 5);
tile.collisionCallback = (sprite, tile) => {
    // Custom logic for this specific tile
};

타일 콜백을 사용하려면 바디와 레이어 사이에 활성 물리 콜라이더/중첩이 있어야 합니다.

타일 조회

const tile = layer.getTileAt(10, 5);               // By tile coords (or null)
const tile = layer.getTileAt(10, 5, true);          // nonNull: Tile with index -1 instead of null
const tile = layer.getTileAtWorldXY(worldX, worldY); // By world coords
const exists = layer.hasTileAt(10, 5);              // Boolean check// Region queries
const tiles = layer.getTilesWithin(0, 0, 10, 10);            // Tile coord region
const tiles = layer.getTilesWithinWorldXY(x, y, w, h);       // World coord region
const tiles = layer.getTilesWithinShape(circle);              // Shape overlap// Functional queries
const water = layer.filterTiles(t => t.properties.type === 'water');
const spawn = layer.findTile(t => t.properties.isSpawn);
layer.forEachTile(t => { /* iterate all tiles */ });

실행 시 타일 수정

layer.putTileAt(5, 10, 10);                      // Place tile index 5 at (10, 10)
layer.putTileAtWorldXY(5, worldX, worldY);        // Place by world coords
layer.putTilesAt([[1, 2], [3, 4]], 10, 10);       // Place a 2x2 grid
layer.removeTileAt(10, 10);                       // Remove tile
layer.fill(1, 0, 0, 10, 10);                     // Fill 10x10 region with index 1
layer.replaceByIndex(5, 10);                      // Replace all index-5 with index-10
layer.copy(0, 0, 5, 5, 20, 20);                  // Copy 5x5 from (0,0) to (20,20)
layer.randomize(0, 0, 10, 10, [1, 2, 3, 4]);     // Random tiles in region
layer.weightedRandomize([{ index: 1, weight: 4 }, { index: 2, weight: 1 }], 0, 0, 10, 10);
layer.shuffle(0, 0, 10, 10);                     // Shuffle tiles in region

좌표 변환

const tileXY = layer.worldToTileXY(worldX, worldY);   // World -> tile coords
const worldXY = layer.tileToWorldXY(tileX, tileY);    // Tile -> world coords// Reuse a vector to avoid allocation
const vec = new Phaser.Math.Vector2();
layer.worldToTileXY(worldX, worldY, true, vec);  // snapToFloor = true

오브젝트 레이어(타일형)

타일형 오브젝트 레이어는 점, 직사각형 및 스프라이트 배치를 정의합니다. createFromObjects 다음 Tilemap:

// Create sprites from all objects on the 'Enemies' object layer
const enemies = map.createFromObjects('Enemies', {
    gid: 26,          // Match by tile GID
    classType: Enemy   // Custom class extending Sprite
});// Match by name
const coins = map.createFromObjects('Items', {
    name: 'coin',
    key: 'coin-texture',
    frame: 0
});// Match by type
const spawns = map.createFromObjects('Spawns', {
    type: 'player-spawn'
});// Access raw object layer data
const objectLayer = map.getObjectLayer('Enemies');
objectLayer.objects.forEach(obj => {
    console.log(obj.name, obj.x, obj.y, obj.properties);
});

createFromObjects(layerName, config, useTileset) 다음과 같은 구성 옵션을 사용하십시오: id, gid, name, type, classType (기본값 Sprite), scene, container, key, frame, ignoreTileset.

애니메이션 타일

타일 애니메이션은 Tiled의 타일셋 편집기에서 정의되며 자동으로 파싱됩니다. TilemapLayerTilemapGPULayer 모두 애니메이션 타일을 지원합니다. TilemapLayerBaseElapseTimer 를 사용하여 preUpdate.

등각 투영, 육각형 및 엇갈린 맵

// Isometric map
const map = this.add.tilemap('iso-map');
const tileset = map.addTilesetImage('iso-tiles', 'iso-img');
const layer = map.createLayer('Ground', tileset);// Get tile at world coords in isometric space
const tile = layer.getIsoTileAtWorldXY(worldX, worldY);// TilemapGPULayer does NOT support iso/hex/staggered - use TilemapLayer

orientation 속성은 Tiled 데이터에서 설정됩니다. 좌표 변환 함수는 방향에 따라 자동으로 선택됩니다.

API 빠른 참조

타일맵 (데이터 컨테이너 - 렌더링되지 않음)

대부분의 타일 쿼리/충돌/조작 메서드는 Tilemap (추가 layer 매개변수 포함)과 TilemapLayerBase (매개변수 없음) 양쪽 모두에 존재합니다. 레이어에서 직접 호출하는 것을 권장합니다.

TilemapLayerBase (렌더링되는 레이어 - CPU 및 GPU)

충돌: setCollision(indexes), setCollisionBetween(start, stop), setCollisionByProperty(props), setCollisionByExclusion(indexes), setCollisionFromCollisionGroup(), setTileIndexCallback(indexes, cb, ctx), setTileLocationCallback(x, y, w, h, cb, ctx)

타일 쿼리: getTileAt(x, y, nonNull), getTileAtWorldXY(wx, wy, nonNull, cam), getTilesWithin(x, y, w, h, opts), getTilesWithinWorldXY(wx, wy, w, h, opts, cam), getTilesWithinShape(shape, opts, cam), hasTileAt(x, y), hasTileAtWorldXY(wx, wy, cam), filterTiles(cb), findTile(cb), forEachTile(cb)

타일 조작: putTileAt(tile, x, y), putTileAtWorldXY(tile, wx, wy), putTilesAt(arr, x, y), removeTileAt(x, y), fill(index, x, y, w, h), copy(sx, sy, w, h, dx, dy), randomize(x, y, w, h, indexes), weightedRandomize(weights, x, y, w, h), shuffle(x, y, w, h), swapByIndex(a, b), replaceByIndex(find, replace), createFromTiles(indexes, replacements, config)

좌표: worldToTileXY(wx, wy, snap, vec, cam), tileToWorldXY(tx, ty, vec, cam)

TilemapGPULayer (추가)

타일 속성

index (숫자, -1=비어 있음), x/y (타일 좌표), pixelX/pixelY (레이어 기준 픽셀 위치), width/height, properties (Tiled의 객체), collideLeft/Right/Up/Down (부울), collisionCallback (함수), tint (숫자), rotation (숫자), alpha, flipX/flipY, physics (엔진 데이터용 객체)

주의 사항

  1. 타일셋 이름은 Tiled에서 정의된 것과 정확히 일치해야 합니다. addTilesetImage 의 첫 번째 인수는 Phaser의 텍스처 키가 아니라 Tiled에서 정의된 타일셋 이름입니다. 두 이름이 일치하지 않으면 null 가 반환되며 콘솔에 경고 메시지가 표시됩니다.

  2. 레이어 이름은 Tiled의 이름과 정확히 일치해야 합니다. createLayer 는 Tiled의 레이어 이름(또는 레이어 인덱스)을 사용합니다. 그룹 레이어의 자식 요소 앞에는 'GroupName/LayerName'.

  3. 각 레이어는 한 번만 생성할 수 있습니다. createLayer 를 호출하면 null 경고 메시지와 함께 반환됩니다. 레이어 데이터는 하나의 레이어 게임 오브젝트에만 연결될 수 있습니다.

  4. setCollision 물리 콜라이더가 작동하려면 반드시 호출되어야 합니다. 타일을 충돌 가능으로 표시하지 않으면, this.physics.add.collider() 는 모든 타일을 통과합니다.

  5. TilemapGPULayer는 정투영 방식만 지원합니다. 등각 투영, 육각형 또는 엇갈린 배열의 맵은 지원하지 않습니다. 또한 레이어당 하나의 타일셋만 지원합니다.

  6. TilemapGPULayer는 수동으로 텍스처를 재생성해야 합니다. putTileAt 또는 기타 편집 메서드를 호출한 후, generateLayerDataTexture() 를 호출해야 하며, 그렇지 않으면 변경 사항이 반영되지 않습니다.

  7. "이미지 모음(Collection of Images)" 타일셋은 지원되지 않습니다. Tiled 파서는 타일셋 내의 모든 타일이 단일 이미지에 포함되어야 합니다. 내보낸 JSON에 타일셋이 내장되어 있어야 합니다.

  8. 타일 인덱스 -1은 빈 타일을 의미합니다. 많은 메서드는 null 를 반환합니다. nonNull: true 를 전달하면 index === -1 를 전달하여 Tile 객체를 얻으십시오.

  9. insertNull 를 전달하십시오. 타일맵을 생성할 때, insertNull: true 인덱스 -1을 가진 Tile 객체 대신 빈 타일에 대해 null 를 저장합니다. 대규모의 스파스 맵에서는 메모리를 절약할 수 있지만, 빈 셀에 타일을 동적으로 배치하는 것은 불가능해집니다.

  10. 타일 콜백은 물리 시뮬레이션이 활성화된 상태에서만 실행됩니다. setTileIndexCallback 또한 setTileLocationCallback 트리거되려면 물리 콜라이더가 있거나 바디와 레이어 간에 겹침이 있어야 합니다.

  11. 레이어 위치 및 타일 오프셋. 만약 x 그리고 ycreateLayer에서 지정되지 않은 경우, 기본값은 (0, 0)이 아닌 Tiled에서 정의된 레이어 오프셋으로 설정됩니다.

소스 파일 맵

GitHub에서 보기

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

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.

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.

// 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.

// 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
// 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

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

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):

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

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:

// 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":

map.setLayer('Ground');
map.setCollision([1, 2, 3]);  // Applies to current layer
// Or specify a layer explicitly:
map.setCollision([1, 2, 3], true, true, 'Ground');

Physics Integration (Arcade)

// Enable collisions between a sprite and a tilemap layer
this.physics.add.collider(player, groundLayer);// With a callback
this.physics.add.collider(player, groundLayer, (sprite, tile) => {
    if (tile.index === 5) {
        // Hit a special tile
    }
});// Overlap detection instead of collision
this.physics.add.overlap(player, groundLayer, (sprite, tile) => {
    // Player is overlapping this tile
});

The layer must have collision set on its tiles (via setCollision* methods) for physics to detect them. The layer itself has collisionCategory and collisionMask properties for collision filtering.

Tile Properties

Tiles can have custom properties set in Tiled's tileset editor:

// Access tile properties
const tile = layer.getTileAt(10, 5);
console.log(tile.properties.damage);    // Custom property from Tiled
console.log(tile.properties.type);      // Custom property from Tiled// Set collision based on custom properties
layer.setCollisionByProperty({ collides: true });
layer.setCollisionByProperty({ type: ['wall', 'rock'] });

Tile Callbacks

// Callback by tile index - fires when physics body overlaps these tiles
map.setTileIndexCallback([5, 6, 7], (sprite, tile) => {
    // Called for tiles with index 5, 6, or 7
    console.log('Hit tile', tile.index, 'at', tile.x, tile.y);
}, this);// Callback by tile location - fires for tiles in a rectangular area
map.setTileLocationCallback(10, 10, 5, 5, (sprite, tile) => {
    // Called for any tile in the 5x5 region starting at (10, 10)
}, this);// Per-tile callback
const tile = layer.getTileAt(10, 5);
tile.collisionCallback = (sprite, tile) => {
    // Custom logic for this specific tile
};

Tile callbacks require an active physics collider/overlap between the body and the layer.

Querying Tiles

const tile = layer.getTileAt(10, 5);               // By tile coords (or null)
const tile = layer.getTileAt(10, 5, true);          // nonNull: Tile with index -1 instead of null
const tile = layer.getTileAtWorldXY(worldX, worldY); // By world coords
const exists = layer.hasTileAt(10, 5);              // Boolean check// Region queries
const tiles = layer.getTilesWithin(0, 0, 10, 10);            // Tile coord region
const tiles = layer.getTilesWithinWorldXY(x, y, w, h);       // World coord region
const tiles = layer.getTilesWithinShape(circle);              // Shape overlap// Functional queries
const water = layer.filterTiles(t => t.properties.type === 'water');
const spawn = layer.findTile(t => t.properties.isSpawn);
layer.forEachTile(t => { /* iterate all tiles */ });

Modifying Tiles at Runtime

layer.putTileAt(5, 10, 10);                      // Place tile index 5 at (10, 10)
layer.putTileAtWorldXY(5, worldX, worldY);        // Place by world coords
layer.putTilesAt([[1, 2], [3, 4]], 10, 10);       // Place a 2x2 grid
layer.removeTileAt(10, 10);                       // Remove tile
layer.fill(1, 0, 0, 10, 10);                     // Fill 10x10 region with index 1
layer.replaceByIndex(5, 10);                      // Replace all index-5 with index-10
layer.copy(0, 0, 5, 5, 20, 20);                  // Copy 5x5 from (0,0) to (20,20)
layer.randomize(0, 0, 10, 10, [1, 2, 3, 4]);     // Random tiles in region
layer.weightedRandomize([{ index: 1, weight: 4 }, { index: 2, weight: 1 }], 0, 0, 10, 10);
layer.shuffle(0, 0, 10, 10);                     // Shuffle tiles in region

Coordinate Conversion

const tileXY = layer.worldToTileXY(worldX, worldY);   // World -> tile coords
const worldXY = layer.tileToWorldXY(tileX, tileY);    // Tile -> world coords// Reuse a vector to avoid allocation
const vec = new Phaser.Math.Vector2();
layer.worldToTileXY(worldX, worldY, true, vec);  // snapToFloor = true

Object Layers (Tiled)

Tiled object layers define points, rectangles, and sprite placement. Use createFromObjects on the Tilemap:

// Create sprites from all objects on the 'Enemies' object layer
const enemies = map.createFromObjects('Enemies', {
    gid: 26,          // Match by tile GID
    classType: Enemy   // Custom class extending Sprite
});// Match by name
const coins = map.createFromObjects('Items', {
    name: 'coin',
    key: 'coin-texture',
    frame: 0
});// Match by type
const spawns = map.createFromObjects('Spawns', {
    type: 'player-spawn'
});// Access raw object layer data
const objectLayer = map.getObjectLayer('Enemies');
objectLayer.objects.forEach(obj => {
    console.log(obj.name, obj.x, obj.y, obj.properties);
});

createFromObjects(layerName, config, useTileset) config options: id, gid, name, type, classType (default Sprite), scene, container, key, frame, ignoreTileset.

Animated Tiles

Tile animations are defined in Tiled's tileset editor and parsed automatically. Both TilemapLayer and TilemapGPULayer support animated tiles. The TilemapLayerBase uses ElapseTimer to track animation time via preUpdate.

Isometric, Hexagonal, and Staggered Maps

// Isometric map
const map = this.add.tilemap('iso-map');
const tileset = map.addTilesetImage('iso-tiles', 'iso-img');
const layer = map.createLayer('Ground', tileset);// Get tile at world coords in isometric space
const tile = layer.getIsoTileAtWorldXY(worldX, worldY);// TilemapGPULayer does NOT support iso/hex/staggered - use TilemapLayer

The map orientation property is set from Tiled data. Coordinate conversion functions are automatically selected based on orientation.

API Quick Reference

Tilemap (data container - not rendered)

Most tile query/collision/manipulation methods exist on both Tilemap (with extra layer param) and TilemapLayerBase (without). Prefer calling on the layer directly.

TilemapLayerBase (rendered layer - CPU and GPU)

Collision: setCollision(indexes), setCollisionBetween(start, stop), setCollisionByProperty(props), setCollisionByExclusion(indexes), setCollisionFromCollisionGroup(), setTileIndexCallback(indexes, cb, ctx), setTileLocationCallback(x, y, w, h, cb, ctx)

Tile queries: getTileAt(x, y, nonNull), getTileAtWorldXY(wx, wy, nonNull, cam), getTilesWithin(x, y, w, h, opts), getTilesWithinWorldXY(wx, wy, w, h, opts, cam), getTilesWithinShape(shape, opts, cam), hasTileAt(x, y), hasTileAtWorldXY(wx, wy, cam), filterTiles(cb), findTile(cb), forEachTile(cb)

Tile manipulation: putTileAt(tile, x, y), putTileAtWorldXY(tile, wx, wy), putTilesAt(arr, x, y), removeTileAt(x, y), fill(index, x, y, w, h), copy(sx, sy, w, h, dx, dy), randomize(x, y, w, h, indexes), weightedRandomize(weights, x, y, w, h), shuffle(x, y, w, h), swapByIndex(a, b), replaceByIndex(find, replace), createFromTiles(indexes, replacements, config)

Coordinates: worldToTileXY(wx, wy, snap, vec, cam), tileToWorldXY(tx, ty, vec, cam)

TilemapGPULayer (additional)

Tile Properties

index (number, -1=empty), x/y (tile coords), pixelX/pixelY (pixel pos relative to layer), width/height, properties (object from Tiled), collideLeft/Right/Up/Down (boolean), collisionCallback (function), tint (number), rotation (number), alpha, flipX/flipY, physics (object for engine data)

Gotchas

  1. Tileset name must match Tiled exactly. The first argument to addTilesetImage is the tileset name as defined in Tiled, not the Phaser texture key. If they don't match, you get null back and a console warning.

  2. Layer name must match Tiled exactly. createLayer takes the layer name from Tiled (or layer index). Group layer children are prefixed with 'GroupName/LayerName'.

  3. Each layer can only be created once. Calling createLayer with the same layer ID twice returns null with a warning. The layer data can only be associated with one layer Game Object.

  4. setCollision must be called before physics colliders work. Without marking tiles as collidable, this.physics.add.collider() will pass through all tiles.

  5. TilemapGPULayer is orthographic only. It does not support isometric, hexagonal, or staggered maps. It also only supports a single tileset per layer.

  6. TilemapGPULayer requires manual texture regeneration. After calling putTileAt or other edit methods, call generateLayerDataTexture() or the changes won't appear.

  7. "Collection of Images" tilesets are not supported. The Tiled parser requires all tiles in a tileset to be in a single image. Embedded tilesets in the exported JSON are required.

  8. Tile index -1 means empty. Many methods return null for empty tiles by default. Pass nonNull: true to get a Tile object with index === -1 instead.

  9. insertNull in tilemap factory. When creating a tilemap, insertNull: true stores null for empty tiles instead of Tile objects with index -1. Saves memory for large sparse maps but prevents dynamic tile placement in empty cells.

  10. Tile callbacks only fire with active physics. setTileIndexCallback and setTileLocationCallback require a physics collider or overlap between the body and the layer to trigger.

  11. Layer position and Tiled offset. If x and y are not specified in createLayer, they default to the layer offset defined in Tiled, not (0, 0).

Source File Map

모든 파일

0개 파일

tilemaps 설치

스킬 파일을 다운로드하여 .claude/skills/ 디렉터리에 압축을 풀어주세요.

ZIP 다운로드

저장소를 클론하고 스킬 파일을 프로젝트에 복사하세요.

git clone https://github.com/phaserjs/phaser/tree/master/skills/tilemaps # Copy the skill folder to .claude/skills/ or .codex/skills/

복사 복사
빠른 설정: skill 폴더를 .claude/skills/로 복사하면 Claude가 해당 스킬을 자동으로 감지하여 사용합니다.
저장소 phaserjs/phaser

관련 스킬

multica-creating-agents
업데이트 된 시간 2026년 8월 12일
v4-new-features
업데이트 된 시간 2026년 8월 4일
agent-github-pr-manager
업데이트 된 시간 2026년 8월 3일
pixijs-application
업데이트 된 시간 2026년 8월 4일
OR