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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    element;

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('einstein', 'assets/pics/ra-einstein.png');
    }

    create ()
    {
        const div = document.createElement('div');
        div.style = 'background-color: lime; width: 220px; height: 100px; font: 48px Arial; font-weight: bold';
        div.innerText = 'Phaser 3';

        this.element = this.add.dom(400, 300, div);
        this.element.setPerspective(800);

        // element.rotate3d.set(1, 0, 0, 0);
        this.element.rotate3d.set(0, 1, 0, 0);

        this.tweens.add({
            targets: this.element.rotate3d,
            w: 80,
            duration: 3000,
            ease: 'Sine.easeInOut',
            loop: -1,
            yoyo: true
        });

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

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

const game = new Phaser.Game(config);

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

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

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('einstein', 'assets/pics/ra-einstein.png');
}

Метод create — это сердце примера. Здесь создается DOM-элемент, настраивается его стиль и текст, а затем он добавляется в игровой мир.

Создание и добавление DOM-элемента

Внутри create сначала создается обычный HTML div с помощью нативного JavaScript. Ему задаются CSS-стили: цвет фона, размеры и шрифт.

const div = document.createElement('div');
div.style = 'background-color: lime; width: 220px; height: 100px; font: 48px Arial; font-weight: bold';
div.innerText = 'Phaser 3';

Затем этот элемент добавляется в сцену с помощью фабрики this.add.dom. Первые два аргумента — это координаты (x, y) для позиционирования элемента. Важно: для работы DOM-элементов в конфиге игры должен быть активирован dom.createContainer: true.

this.element = this.add.dom(400, 300, div);

Настройка 3D-перспективы и вращения

Чтобы элемент мог вращаться в 3D, ему нужно задать перспективу. Метод setPerspective определяет, насколько сильно будет выражен эффект глубины. Чем меньше значение, тем более выраженной будет перспектива.

this.element.setPerspective(800);

Вращение управляется свойством rotate3d, которое является объектом типа Phaser.Math.Vector4. Его компоненты (x, y, z, w) соответствуют оси вращения и углу. В примере изначально устанавливается вращение вокруг оси Y (второй параметр 1).

this.element.rotate3d.set(0, 1, 0, 0);

Параметр `w` здесь инициализируется нулем — это начальный угол вращения.

Анимация с помощью твинов

Phaser предоставляет мощную систему твинов для плавной анимации свойств. В данном случае анимируется именно свойство `w(угол) вектораrotate3d`.

this.tweens.add({
    targets: this.element.rotate3d,
    w: 80,
    duration: 3000,
    ease: 'Sine.easeInOut',
    loop: -1,
    yoyo: true
});

Ключевые параметры: - targets: объект, который будет анимироваться (this.element.rotate3d). - `w`: целевое значение угла (80 градусов). - duration: длительность анимации в миллисекундах. - ease: функция плавности, которая делает движение более естественным. - loop: -1: бесконечное повторение анимации. - yoyo: true: анимация будет проигрываться вперед и назад, создавая колебательный эффект. В результате элемент плавно вращается вокруг оси Y на 80 градусов в одну и другую сторону.

Интеграция с игровым миром

DOM-элементы в Phaser ведут себя как обычные игровые объекты. Они рендерятся поверх или под другими объектами в зависимости от порядка добавления. В примере после создания анимированного элемента добавляется фоновое изображение.

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

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

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

Использование DOM-элементов с 3D-преобразованиями позволяет быстро создавать сложные интерфейсные анимации прямо внутри игровой сцены Phaser. Вы можете экспериментировать: меняйте оси вращения в rotate3d.set, например, на (1, 0, 0, 0) для вращения вокруг X, или комбинируйте несколько твинов для сложных траекторий. Попробуйте анимировать не только угол (`w`), но и координаты элемента, создавая параллакс-эффекты. Это мощный инструмент для прототипирования и реализации нестандартного HUD.