tilemaps
phaserjs/phaser
Phaser 4 でタイルマップを扱う際に、このスキルを活用してください。Tiled の JSON マップの読み込み、タイルマップレイヤーの作成、タイルの衝突判定、動的タイル、タイルのプロパティ、タイルマップのカメラカリングについて解説します。トリガー対象:タイルマップ、Tiled、タイルマップレイヤー、タイルの衝突判定、タイルのプロパティ。
...すべて拡張しますTilemaps
PhaserのTilemapsは、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) - 解析されたマップデータ内にそのタイルセット名がすでに存在する場合、既存の Tileset オブジェクトをそのテクスチャで更新します。存在しない場合(Tiled 以外のマップ)、新しい Tileset を作成します。
重要:PhaserのTiledパーサーは、「画像のコレクション」形式のタイルセットをサポートしていません。すべてのタイルは、1つのタイルセットにつき1つのタイルセット画像に収められている必要があります。
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 は、 TilemapLayer。シェーダーを使用してレイヤー全体を単一のクワッドとしてレンダリングするため、処理のほぼすべてがGPUに依存します。
// Pass gpu: true as the 5th argument to createLayer
const layer = map.createLayer('Ground', tileset, 0, 0, true);
機能:
- レイヤーごとに1つのタイルセットのみ(マルチタイルセットには非対応)
- タイルマップの最大サイズ:4096x4096タイル
- 最大ユニークタイルID数:2^23(8,388,608)
- タイルの反転およびタイルアニメーションに対応
- 正投影マップのみ(アイソメトリック/ヘックス/スタッガードは非対応)
- LINEARフィルタリングによる滑らかなタイル境界(継ぎ目なし)
- NEARESTフィルタリングによるシャープなピクセル
制限事項:
- レイヤーの編集内容は自動的に表示されません。
generateLayerDataTexture()を呼び出してください。 - WebGLレンダラーのみ(Canvasによるフォールバックなし)
- 1つのレイヤーで複数のタイルセットを使用することはできません
// If you edit tiles on a GPU layer, regenerate the data texture:
gpuLayer.putTileAt(5, 10, 10);
gpuLayer.generateLayerDataTexture();
TilemapLayerBase
両方の TilemapLayer および TilemapGPULayer を継承 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);
1つのレイヤーで複数のタイルセットを使用できます(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');
物理演算の統合(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
});
物理演算がこれらを検知できるように、レイヤーのタイルには衝突設定が有効になっている必要があります( setCollision* メソッドを介して)設定されていなければなりません。レイヤー自体には collisionCategory および collisionMask プロパティを備えています。
タイルのプロパティ
タイルには、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のタイルセットエディタで定義され、自動的に解析されます。 TilemapLayer と TilemapGPULayer はアニメーションタイルに対応しています。 TilemapLayerBase は ElapseTimer を使用して、 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 (エンジンデータ用オブジェクト)
注意点
-
タイルセット名は、Tiledでの表記と完全に一致している必要があります。
addTilesetImageの最初の引数は、Phaserのテクスチャキーではなく、Tiledで定義されたタイルセット名です。これらが一致しない場合、nullが返され、コンソールに警告が表示されます。 -
レイヤー名はTiledでの表記と完全に一致する必要があります。
createLayerは、Tiledのレイヤー名(またはレイヤーインデックス)を受け取ります。グループのレイヤー子要素には'GroupName/LayerName'. -
各レイヤーは一度しか作成できません。
createLayerを呼び出すと、警告と共にnullが警告と共に返されます。レイヤーデータは、1つのレイヤーGameObjectにのみ関連付けることができます。 -
setCollision物理コライダーが機能するには、事前にを呼び出す必要があります。タイルを「collidable」としてマークしないと、this.physics.add.collider()はすべてのタイルを透過します。 -
TilemapGPULayerは正投影のみに対応しています。アイソメトリック、六角形、またはずらして配置されたマップには対応していません。また、レイヤーごとに1つのタイルセットのみをサポートしています。
-
TilemapGPULayer では、手動によるテクスチャの再生成が必要です。
putTileAtやその他の編集メソッドを呼び出した後は、generateLayerDataTexture()を呼び出さないと、変更が反映されません。 -
「画像のコレクション」形式のタイルセットはサポートされていません。Tiledパーサーでは、タイルセット内のすべてのタイルが単一の画像に含まれている必要があります。エクスポートされたJSONには、埋め込みタイルセットが含まれている必要があります。
-
タイルインデックス -1 は空を意味します。多くのメソッドは、デフォルトで
nullを返します。nonNull: trueを渡すと、代わりにindex === -1を指定して、Tileオブジェクトを取得してください。代わりに、 -
insertNullを指定して、Tileオブジェクトを取得してください。タイルマップを作成する際は、insertNull: trueはnullを保存します。これにより、大規模で疎なマップではメモリを節約できますが、空のセルへの動的なタイル配置は行われなくなります。 -
Tileのコールバックは、物理演算が有効な場合にのみ発火します。
setTileIndexCallbackまた、setTileLocationCallbackトリガーするには、フィジックスコライダー、またはボディとレイヤーの間に重なりが必要です。 -
レイヤーの位置とタイルオフセット。もし
xおよびyがcreateLayerでおよびが指定されていない場合、デフォルト値は (0, 0) ではなく、Tiled で定義されたレイヤーオフセットになります。
ソースファイルマップ
Tilemaps
Phaser Tilemaps render tile-based levels from Tiled JSON, CSV, or raw 2D arrays. A
Tilemapholds parsed map data and provides methods to add tilesets, create layers, set collision, and query tiles. Layers (TilemapLayerorTilemapGPULayer) 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 originwidth,height- tile size in pixelsproperties- custom properties from Tiled (object)collideLeft,collideRight,collideUp,collideDown- per-edge collision flagsfaceLeft,faceRight,faceTop,faceBottom- interesting face flags for collision optimizationcollisionCallback- per-tile collision callback functiontint- tint color value (default0xffffff)tintMode- tint blend mode (defaultTintModes.MULTIPLY)rotation- rotation anglephysics- 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
-
Tileset name must match Tiled exactly. The first argument to
addTilesetImageis the tileset name as defined in Tiled, not the Phaser texture key. If they don't match, you getnullback and a console warning. -
Layer name must match Tiled exactly.
createLayertakes the layer name from Tiled (or layer index). Group layer children are prefixed with'GroupName/LayerName'. -
Each layer can only be created once. Calling
createLayerwith the same layer ID twice returnsnullwith a warning. The layer data can only be associated with one layer Game Object. -
setCollisionmust be called before physics colliders work. Without marking tiles as collidable,this.physics.add.collider()will pass through all tiles. -
TilemapGPULayer is orthographic only. It does not support isometric, hexagonal, or staggered maps. It also only supports a single tileset per layer.
-
TilemapGPULayer requires manual texture regeneration. After calling
putTileAtor other edit methods, callgenerateLayerDataTexture()or the changes won't appear. -
"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.
-
Tile index -1 means empty. Many methods return
nullfor empty tiles by default. PassnonNull: trueto get a Tile object withindex === -1instead. -
insertNullin tilemap factory. When creating a tilemap,insertNull: truestoresnullfor empty tiles instead of Tile objects with index -1. Saves memory for large sparse maps but prevents dynamic tile placement in empty cells. -
Tile callbacks only fire with active physics.
setTileIndexCallbackandsetTileLocationCallbackrequire a physics collider or overlap between the body and the layer to trigger. -
Layer position and Tiled offset. If
xandyare not specified increateLayer, 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/
コピー





家
