О чем этот пример
При разработке игр часто возникает задача разместить на уровне множество однотипных интерактивных объектов, например, монеток или бонусов. Рисовать их вручную — долго и неудобно. В этой статье мы рассмотрим, как использовать редактор карт Tiled для удобного размещения объектов и как с помощью одного метода `createFromObjects` превратить их в полноценные спрайты Phaser, готовые к анимации и физике. Этот подход ускоряет создание контента и делает процесс более наглядным.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
controls;
map;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.tilemapTiledJSON('map', 'assets/tilemaps/maps/level-with-coin-objects.json');
this.load.spritesheet('coin', 'assets/sprites/coin.png', { frameWidth: 32, frameHeight: 32 });
this.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png');
}
create ()
{
this.map = this.add.tilemap('map');
const tiles = this.map.addTilesetImage('ground_1x1');
const layer = this.map.createLayer('Tile Layer', tiles);
this.anims.create({
key: 'spin',
frames: this.anims.generateFrameNumbers('coin', { start: 0, end: 5 }),
frameRate: 16,
repeat: -1
});
// We convert all of the Tiled objects with an ID of 26 into sprites. They will get their width
// & height from the Tiled tile object. Any custom properties on the tile object will also be
// passed to the sprite creator (e.g. one of the tile object's has an alpha of 0.5).
// var coins = map.createFromObjects('Coin Object Layer', 26, { key: 'coin' });
const coins = this.map.createFromObjects('Coin Object Layer', { gid: 26, key: 'coin' });
this.anims.play('spin', coins);
const cursors = this.input.keyboard.createCursorKeys();
const controlConfig = {
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
up: cursors.up,
down: cursors.down,
acceleration: 0.04,
drag: 0.0005,
maxSpeed: 0.7
};
this.controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
}
update (time, delta)
{
this.controls.update(delta);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
pixelArt: true,
scene: Example
};
const game = new Phaser.Game(config);
Подготовка: карта и ресурсы
Всё начинается с загрузки ресурсов. В методе preload мы загружаем карту в формате JSON, созданную в Tiled, лист спрайтов для монетки и изображение тайла для земли. Обратите внимание на использование setBaseURL — это удобный способ задать базовый путь для всех последующих загрузок.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.tilemapTiledJSON('map', 'assets/tilemaps/maps/level-with-coin-objects.json');
this.load.spritesheet('coin', 'assets/sprites/coin.png', { frameWidth: 32, frameHeight: 32 });
this.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png');
}
Создание слоёв и анимации
В методе create мы создаём саму карту (tilemap), добавляем к ней набор тайлов (tileset) и создаём слой для отрисовки. Это стандартный процесс для работы с тайловыми картами в Phaser.
Отдельно создаётся анимация spin для вращения монетки. Мы используем generateFrameNumbers, чтобы автоматически сгенерировать кадры анимации из листа спрайтов coin.
create ()
{
this.map = this.add.tilemap('map');
const tiles = this.map.addTilesetImage('ground_1x1');
const layer = this.map.createLayer('Tile Layer', tiles);
this.anims.create({
key: 'spin',
frames: this.anims.generateFrameNumbers('coin', { start: 0, end: 5 }),
frameRate: 16,
repeat: -1
});
Волшебство метода `createFromObjects`
Ключевой момент — создание игровых объектов из данных Tiled. В редакторе карт мы создали специальный слой объектов (Coin Object Layer) и разместили на нём тайлы с монетками (у этих тайлов в наборе GID = 26).
Метод this.map.createFromObjects находит все объекты на указанном слое с заданным GID и создаёт из них спрайты Phaser. В параметрах мы указываем, какой ключ текстуры (key: 'coin') использовать для этих спрайтов. Метод автоматически унаследует от объектов Tiled их координаты, размеры и любые пользовательские свойства (например, прозрачность).
После создания массива спрайтов coins, мы легко запускаем на них одну и ту же анимацию spin.
const coins = this.map.createFromObjects('Coin Object Layer', { gid: 26, key: 'coin' });
this.anims.play('spin', coins);
Управление камерой для навигации
Чтобы можно было осмотреть всю карту, в примере реализовано плавное управление камерой с клавиатуры. Создаётся экземпляр SmoothedKeyControl, который обрабатывает нажатия стрелок и двигает камеру с заданным ускорением и максимальной скоростью. Обновление состояния управления происходит в методе update.
const cursors = this.input.keyboard.createCursorKeys();
const controlConfig = {
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
up: cursors.up,
down: cursors.down,
acceleration: 0.04,
drag: 0.0005,
maxSpeed: 0.7
};
this.controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
update (time, delta)
{
this.controls.update(delta);
}
Что попробовать дальше
Метод createFromObjects — это мощный мост между дизайном уровней в Tiled и логикой игры в Phaser. Он позволяет дизайнеру легко расставлять объекты, а разработчику — мгновенно получать их в коде как готовые сущности. Для экспериментов попробуйте:
1. Добавить пользовательские свойства объектам в Tiled (например, points: 100) и читать их в коде спрайта.
2. Использовать разные GID для создания различных типов объектов (монетки, ловушки, ключи) за один вызов метода.
3. Настроить физические тела для созданных спрайтов, чтобы они могли сталкиваться с игроком.
