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

Создание игровых интерфейсов часто требует элементов, которые сложно реализовать на Canvas или WebGL — сложные формы, HTML-формами или динамическим текстом. Phaser 3 предоставляет систему DOM-элементов, позволяющую встраивать обычные HTML-элементы прямо в игровую сцену, позиционируя и анимируя их как обычные игровые объекты. Это открывает путь к созданию гибридных интерфейсов, где часть контента рендерится браузером, а часть — игровым движком.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const style = {
            'background-color': 'lime',
            width: '220px',
            height: '100px',
            font: '48px Arial',
            'font-weight': 'bold'
        };

        const element = this.add.dom(400, 300, 'div', style, 'Phaser 3');

        // this.tweens.add({
        //     targets: element,
        //     _y: 600,
        //     _alpha: 0.5,
        //     angle: 200,
        //     duration: 3000,
        //     scaleX: 2,
        //     scaleY: 2,
        //     ease: 'Sine.easeInOut',
        //     loop: -1,
        //     yoyo: true
        // });

        // this.add.image(400, 300, 'einstein');
    }
}

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    dom: {
        createContainer: true
    },
    scene: Example
};

const game = new Phaser.Game(config);

Настройка проекта для работы с DOM

Чтобы использовать DOM-элементы в Phaser, необходимо включить соответствующую систему в конфигурации игры. Это делается через свойство dom в основном конфигурационном объекте.

const config = {
    type: Phaser.AUTO,
    // ... другие настройки ...
    dom: {
        createContainer: true
    },
    scene: Example
};

Ключевой параметр createContainer: true указывает Phaser автоматически создать и настроить контейнер для DOM-элементов. Без этой настройки методы работы с DOM будут недоступны.

Создание и стилизация DOM-объекта

DOM-объекты создаются с помощью метода this.add.dom(). Этот метод принимает координаты (X, Y), тип создаваемого HTML-элемента (например, 'div'), объект со стилями и необязательный текстовый контент.

Внутри метода create() сцены сначала определяется объект стилей. Это обычный JavaScript-объект, где ключи — это CSS-свойства, а значения — строки.

const style = {
    'background-color': 'lime',
    width: '220px',
    height: '100px',
    font: '48px Arial',
    'font-weight': 'bold'
};

Затем создается сам элемент. В данном случае это div с заданными стилями и текстом 'Phaser 3', расположенный в центре экрана (400, 300).

const element = this.add.dom(400, 300, 'div', style, 'Phaser 3');

Возвращаемый объект element является экземпляром Phaser.GameObjects.DOMElement и может использоваться для дальнейших манипуляций.

Анимация DOM-объектов через систему Tween

Одно из главных преимуществ интеграции — возможность анимировать DOM-элементы с помощью встроенной в Phaser системы твинов (this.tweens). Это позволяет применять плавные переходы для свойств позиции, прозрачности, масштаба и вращения.

this.tweens.add({
    targets: element,        // Цель анимации — наш DOM-элемент
    _y: 600,                 // Конечная координата Y (обратите внимание на нижнее подчеркивание)
    _alpha: 0.5,             // Конечное значение прозрачности
    angle: 200,              // Конечный угол поворота в градусах
    duration: 3000,          // Длительность анимации в миллисекундах
    scaleX: 2,               // Масштаб по оси X
    scaleY: 2,               // Масштаб по оси Y
    ease: 'Sine.easeInOut',  // Функция плавности (easing)
    loop: -1,                // Бесконечное повторение (-1)
    yoyo: true               // Возврат к начальному состоянию после завершения цикла
});

Важное замечание: для управления свойствами, которые конфликтуют с геттерами/сеттерами самого DOM-элемента (как `y), Phaser использует имена с нижним подчеркиванием:_y,_x,_alpha`. Это позволяет движку управлять трансформациями через CSS, а не перезаписывать свойства объекта.

Совместное использование с другими игровыми объектами

DOM-элементы существуют в том же пространстве сцены, что и объекты Canvas/WebGL. Это позволяет создавать сложные композиции.

// Создание DOM-элемента (код из примера выше)
const element = this.add.dom(400, 300, 'div', style, 'Phaser 3');

// Добавление обычного изображения из атласа или текстуры
this.add.image(400, 300, 'einstein');

Порядок добавления объектов определяет их слой (z-index). Объект, добавленный позже, будет отрисовываться поверх предыдущих. DOM-контейнер также имеет свой z-index относительно игрового холста, которым обычно можно управлять через настройки рендерера или порядок создания сцен.

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

Интеграция DOM-элементов в Phaser 3 — мощный инструмент для создания гибридных интерфейсов, где статичный или сложный HTML-контент должен быть частью игрового мира. Вы можете стилизовать элементы с помощью CSS, анимировать их через систему твинов и комбинировать с традиционными игровыми объектами. Для экспериментов попробуйте: создать интерактивную HTML-форму (input, button) внутри игры, управлять видимостью и содержимым элемента в реальном времени или реализовать сложный UI-виджет (например, полосу прогресса с градиентами и текстом), который было бы трудно отрисовать на Canvas.