О чем этот пример

Создание изометрических или гексагональных миров — мощный способ добавить глубину и стиль вашей игре. В Phaser 3 это реализуется через систему тайловых карт (Tilemap). Эта статья покажет, как загрузить изометрическую карту, созданную в редакторе Tiled, и настроить плавное управление камерой с клавиатуры, чтобы игрок мог исследовать ваш мир. Вы научитесь работать с ключевыми методами загрузки (`load.tilemapTiledJSON`), отображения слоев карты (`map.createLayer`) и настройки продвинутого управления камерой через `SmoothedKeyControl`. Этот подход идеален для стратегий, RPG или любых игр с видом сверху.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    controls;

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('tiles', 'assets/tilemaps/iso/tilesets/tileset.png');
        this.load.tilemapTiledJSON('map', 'assets/tilemaps/iso/hexagonal.json');
    }

    create ()
    {
        const map = this.add.tilemap('map');

        const tileset = map.addTilesetImage('tileset', 'tiles');

        map.createLayer('Calque 1', tileset);

        const cursors = this.input.keyboard.createCursorKeys();

        this.cameras.main.setZoom(2);
        this.cameras.main.centerOn(200, 100);

        const controlConfig = {
            camera: this.cameras.main,
            left: cursors.left,
            right: cursors.right,
            up: cursors.up,
            down: cursors.down,
            acceleration: 0.02,
            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: '#2d2d2d',
    parent: 'phaser-example',
    pixelArt: true,
    scene: Example
};

const game = new Phaser.Game(config);

Подготовка и загрузка ресурсов

Все ресурсы загружаются в методе preload. Важно правильно указать базовый URL и имена ресурсов, которые будут использоваться как ключи для доступа к ним позже.

Мы загружаем два основных ресурса: изображение тайлсета (набор плиток) и саму карту в формате JSON, экспортированную из редактора Tiled.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('tiles', 'assets/tilemaps/iso/tilesets/tileset.png');
this.load.tilemapTiledJSON('map', 'assets/tilemaps/iso/hexagonal.json');

- setBaseURL задает общую часть пути для всех загружаемых файлов, что упрощает указание относительных путей. - load.image('tiles', ...) загружает изображение тайлсета и присваивает ему ключ 'tiles'. - load.tilemapTiledJSON('map', ...) загружает структуру карты (расположение слоев и плиток) по ключу 'map'.

Создание карты и визуализация слоя

В методе create мы создаем игровые объекты. Первым делом создается экземпляр тайловой карты и связывается с загруженным тайлсетом.

const map = this.add.tilemap('map');
const tileset = map.addTilesetImage('tileset', 'tiles');
map.createLayer('Calque 1', tileset);

1. this.add.tilemap('map') создает объект Tilemap, используя данные JSON, загруженные под ключом 'map'. 2. map.addTilesetImage('tileset', 'tiles') связывает имя тайлсета из данных Tiled (в данном случае 'tileset') с загруженным изображением по ключу 'tiles'. Это crucial шаг: движок понимает, какими картинками рисовать плитки на карте. 3. map.createLayer('Calque 1', tileset) создает и отображает слой с именем 'Calque 1' (это имя слоя из Tiled), используя связанный тайлсет. Слой становится дочерним объектом сцены.

Настройка камеры и элементов управления

Чтобы игрок мог осматривать большую карту, мы настраиваем камеру и привязываем ее управление к клавишам стрелок.

Сначала получаем ссылку на объект клавиш-стрелок и настраиваем вид камеры.

const cursors = this.input.keyboard.createCursorKeys();
this.cameras.main.setZoom(2);
this.cameras.main.centerOn(200, 100);

- createCursorKeys() возвращает объект для отслеживания состояния стрелок на клавиатуре. - setZoom(2) увеличивает масштаб камеры в 2 раза. - centerOn(200, 100) центрирует камеру на указанных координатах мира.

Затем создается сложный контроллер для плавного перемещения камеры.

const controlConfig = {
    camera: this.cameras.main,
    left: cursors.left,
    right: cursors.right,
    up: cursors.up,
    down: cursors.down,
    acceleration: 0.02,
    drag: 0.0005,
    maxSpeed: 0.7
};
this.controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);

Класс SmoothedKeyControl обеспечивает движение с ускорением и плавным замедлением (drag). Конфиг связывает камеру с клавишами и задает физические параметры движения: ускорение (acceleration), сопротивление (drag) и максимальную скорость (maxSpeed).

Обновление состояния управления

Для работы контроллера SmoothedKeyControl необходимо постоянно обновлять его логику. Это делается в методе update, который вызывается на каждом кадре игры.

update (time, delta)
{
    this.controls.update(delta);
}

Метод controls.update(delta) принимает параметр delta — время, прошедшее с предыдущего кадра в миллисекундах. Это позволяет движению камеры быть плавным и независимым от частоты кадров. Контроллер внутри себя обрабатывает состояние нажатых клавиш и применяет физику (ускорение, трение) к скорости камеры.

Конфигурация игры и запуск

Код завершается созданием и запуском экземпляра игры Phaser.Game с конфигурационным объектом.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    parent: 'phaser-example',
    pixelArt: true,
    scene: Example
};
const game = new Phaser.Game(config);

- type: Определяет рендерер (WebGL или Canvas). Phaser.AUTO позволяет движку выбрать лучший вариант. - width/height: Размер игрового холста. - backgroundColor: Цвет фона до отрисовки сцены. - parent: ID HTML-элемента, в который будет встроен canvas. - pixelArt: Установка в true отключает сглаживание для пиксель-арт графики, что критично для четкого отображения тайлов. - scene: Указывает класс сцены, которая будет запущена первой.

Что попробовать дальше

Вы освоили базовый пайплайн для работы с изометрическими картами в Phaser: от загрузки данных из Tiled до реализации плавного управления камерой. Это основа для создания исследовательских игр. Для экспериментов попробуйте: 1. Загрузить свою карту, созданную в Tiled, и поэксперементировать с разными слоями. 2. Изменить параметры acceleration, drag и maxSpeed в контроллере, чтобы получить разное ощущение от управления камерой — от резкого до очень плавного и инерционного. 3. Добавить зум камеры колесиком мыши, используя событие this.input.on('wheel', ...) и метод this.cameras.main.zoom. 4. Реализовать перемещение камеры к интересующей точке по клику мыши с помощью this.cameras.main.pan(...).