Phaser предоставляет мощный инструмент для работы с тайловыми картами через модуль Tilemap. Тайловая карта состоит из слоев, в которых каждый тайл имеет определённый индекс, соответствующий текстуре из тайлсета. Основная задача при динамическом создании карты из массива — преобразовать двумерный массив чисел в слой тайлов, корректно сопоставив индексы тайлов с графикой.
const mapData = [
[0, 1, 1, 0, 2],
[1, 1, 0, 2, 2],
[0, 2, 2, 1, 0]
];
В этом примере числа 0, 1, 2 представляют разные типы
тайлов: пустой, земля, вода и т.д.
Для начала необходимо создать объект карты без привязки к файлу JSON:
const map = this.make.tilemap({ tileWidth: 32, tileHeight: 32, width: mapData[0].length, height: mapData.length });
tileWidth и tileHeight — размеры одного
тайла в пикселях.width и height — размеры карты в
тайлах.После этого создаётся тайлсет:
const tileset = map.addTilesetImage('terrain', null, 32, 32);
'terrain' — ключ загруженной текстуры тайлсета.null указывает, что используется один тайлсет без
ассоциированного JSON.Для отображения карты нужно создать слой:
const layer = map.createBlankLayer('Layer1', tileset);
Далее осуществляется заполнение слоя на основе массива:
for (let y = 0; y < mapData.length; y++) {
for (let x = 0; x < mapData[y].length; x++) {
const tileIndex = mapData[y][x];
if (tileIndex >= 0) {
layer.putTileAt(tileIndex, x, y);
}
}
}
putTileAt(index, x, y) помещает тайл с заданным
индексом на координаты (x, y) слоя.tileIndex >= 0 позволяет пропускать пустые
тайлы, если 0 соответствует прозрачной области.Phaser позволяет изменять тайлы в реальном времени, что важно для создания интерактивных уровней:
layer.putTileAt(2, 1, 0); // заменяет тайл в позиции (1,0) на воду
layer.removeTileAt(3, 2); // удаляет тайл в позиции (3,2)
Использование
layer.setTileIndexCallback(index, callback, context)
позволяет реагировать на взаимодействие с конкретными тайлами:
layer.setTileIndexCallback(2, (sprite, tile) => {
sprite.setVelocity(0); // остановка игрока на воде
}, this);
Для создания процедурно сгенерированных уровней удобно использовать генерацию массива перед созданием тайлов:
const width = 20;
const height = 15;
const proceduralMap = Array.from({ length: height }, () =>
Array.from({ length: width }, () => Math.floor(Math.random() * 3))
);
Здесь каждый элемент массива случайно принимает значения 0, 1 или 2,
что позволяет создавать уникальные карты на лету. После этого массив
используется в том же цикле putTileAt.
При работе с большими картами важно минимизировать количество
операций putTileAt во время обновления. Рекомендуется:
fill для однотипных областей.Пример заполнения области одним индексом:
layer.fill(1, 0, 0, width, height); // заполняет прямоугольник землёй
Для интерактивных игр важна коллизия тайлов. Phaser поддерживает её через слой:
layer.setCollision([1, 2]); // тайлы с индексами 1 и 2 вызывают коллизию
this.physics.add.collider(player, layer);
[1, 2] — индексы тайлов, с которыми игрок может
сталкиваться.this.physics.add.collider связывает слой с
объектами физики.Динамическое создание тайловой карты сводится к следующей последовательности:
Tilemap с размерами и
тайлсетом.createBlankLayer.putTileAt или
fill.Такой подход обеспечивает гибкость: карты могут быть статическими, загруженными из JSON, или полностью процедурными, с динамической модификацией во время игры.