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 + изображения, создание карты тайлов, добавление изображения набора тайлов, создание слоя (слоев), настройка коллизий.
Основные концепции
Карта тайлов и слой
Карта Tilemap — это контейнер данных, а не объект отображения. Он хранит проанализированные данные карты (слои, наборы плиток, объекты) и предоставляет методы для работы с ними. 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), он создаёт новый набор плиток.
Важно: парсер Phaser Tiled не поддерживает наборы плиток типа «Коллекция изображений». Все плитки каждого набора должны находиться в одном изображении.
Класс 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 тайлов
- Максимальное количество уникальных идентификаторов плиток: 2^23 (8 388 608)
- Поддерживает зеркальное отражение и анимацию плиток
- Только ортогональные карты (без изометрических, гексагональных и с чередующимся расположением)
- Сглаживание границ плиток с помощью линейной фильтрации (без швов)
- Чёткие пиксели с фильтрацией NEAREST
Ограничения:
- Изменения в слоях не отображаются автоматически. Вызовите
generateLayerDataTexture()после изменения плиток. - Только рендерер WebGL (без резервного варианта Canvas)
- Невозможно использовать несколько наборов тайлов на одном слое
// 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.
Распространённые шаблоны
Создание из JSON-файла Tiled
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');
Интеграция с физикой (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 (контейнер данных — не отображается)
Большинство методов запроса, проверки столкновений и манипуляций с плитками доступны как в 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— это имя набора плиток, как оно определено в Tiled, а не ключ текстуры в Phaser. Если они не совпадают, вы получитеnullи предупреждение в консоли. -
Имя слоя должно точно совпадать с именем в Tiled.
createLayerФункция принимает имя слоя из Tiled (или индекс слоя). К дочерним элементам группового слоя добавляется префикс'GroupName/LayerName'. -
Каждый слой можно создать только один раз. Двукратный вызов
createLayerс одинаковым идентификатором слоя дважды возвращаетnullс предупреждением. Данные слоя могут быть связаны только с одним игровым объектом слоя. -
setCollisionДолжно быть вызвано до того, как начнут работать физические коллайдеры. Если не пометить плитки как поддающиеся столкновениям,this.physics.add.collider()будет проходить сквозь все плитки. -
TilemapGPULayer поддерживает только ортографическую проекцию. Он не поддерживает изометрические, гексагональные или шахматные карты. Кроме того, он поддерживает только один набор тайлов на слой.
-
TilemapGPULayer требует ручной регенерации текстур. После вызова
putTileAtили других методов редактирования необходимо вызватьgenerateLayerDataTexture(), иначе изменения не отобразятся. -
Наборы плиток типа «Коллекция изображений» не поддерживаются. Парсер Tiled требует, чтобы все плитки в наборе находились в одном изображении. Требуется наличие встроенных наборов плиток в экспортированном JSON-файле.
-
Индекс плитки -1 означает пустую плитку. Многие методы по умолчанию возвращают
nullпо умолчанию для пустых плиток. ПередайтеnonNull: true, чтобы получить объект Tile сindex === -1вместо этого. -
insertNullв фабрике карт плиток. При создании карты плитокinsertNull: trueсохраняетnullдля пустых тайлов вместо объектов Tile с индексом -1. Это экономит память для больших разреженных карт, но не позволяет динамически размещать тайлы в пустых ячейках. -
Обратные вызовы Tile срабатывают только при активной физике.
setTileIndexCallbackиsetTileLocationCallbackдля срабатывания требуются физический коллайдер или перекрытие между телом и слоем. -
Положение слоя и смещение плитки. Если
xиyне указаны вcreateLayer, по умолчанию используется смещение слоя, определённое в Tiled, а не (0, 0).
Карта исходного файла
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/
Копировать





Дом
