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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.css('80s', 'assets/loader-tests/80stypography.css');
    }

    create ()
    {
        const h1 = this.add.dom(450, 100, 'h1', null, 'CHROME');

        h1.setClassName('chrome');

        const h2 = this.add.dom(570, 180, 'h2', null, 'Dreams');

        h2.setClassName('dreams');
        h2.setAngle(-15);

        this.tweens.add({
            targets: [ h1, h2 ],
            y: 500,
            duration: 3000,
            ease: 'Sine.easeInOut',
            loop: -1,
            yoyo: true
        });
    }
}

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

const game = new Phaser.Game(config);

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

Перед созданием DOM-элементов необходимо загрузить CSS-файл со стилями. Phaser предоставляет для этого специальный загрузчик css. В методе preload мы устанавливаем базовый URL для загрузки ресурсов и загружаем CSS-файл под ключом '80s'.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.css('80s', 'assets/loader-tests/80stypography.css');
}

Загрузчик this.load.css добавляет содержимое CSS-файла в <head> вашей HTML-страницы, делая классы доступными для любых DOM-элементов, включая создаваемые в игре. Это позволяет использовать внешние стили, веб-шрифты или готовые CSS-анимации.

Создание и стилизация DOM-элементов

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

const h1 = this.add.dom(450, 100, 'h1', null, 'CHROME');
h1.setClassName('chrome');

Метод this.add.dom принимает координаты (x, y), HTML-тег ('h1'), атрибуты (здесь null) и текстовое содержимое ('CHROME'). Созданный объект h1 — это не спрайт, а обертка Phaser для реального HTML-элемента. Метод setClassName('chrome') назначает элементу CSS-класс 'chrome', который должен быть определен в загруженном файле. Стили (цвет, градиент, тени) применяются автоматически.

const h2 = this.add.dom(570, 180, 'h2', null, 'Dreams');
h2.setClassName('dreams');
h2.setAngle(-15);

Второй элемент создается аналогично. Обратите внимание на вызов h2.setAngle(-15). Это метод Phaser для вращения DOM-объекта. Вращение выполняется через CSS-трансформацию transform, которую Phaser применяет к элементу автоматически.

Анимация через систему Tween

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

this.tweens.add({
    targets: [ h1, h2 ],
    y: 500,
    duration: 3000,
    ease: 'Sine.easeInOut',
    loop: -1,
    yoyo: true
});

Здесь создается твин, который одновременно анимирует оба текстовых элемента (targets: [ h1, h2 ]). Они будут перемещаться по оси Y до координаты 500 за 3 секунды с плавным easing. Параметры loop: -1 и yoyo: true заставляют анимацию бесконечно повторяться в прямом и обратном направлении. Координата `yизменяется у DOM-объекта Phaser, который, в свою очередь, обновляет CSS-свойствоtransform` реального HTML-элемента.

Конфигурация игры для работы с DOM

Ключевой момент — правильная настройка конфигурации игры. Без этого DOM-элементы не будут создаваться.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#080808',
    parent: 'phaser-example',
    dom: {
        createContainer: true // Включаем контейнер для DOM-элементов
    },
    scene: Example
};

Объект dom с параметром createContainer: true указывает Phaser создать специальный HTML-контейнер (обычно <div>), в который будут помещаться все DOM-объекты сцены. Этот контейнер позиционируется и масштабируется вместе с игрой, что обеспечивает корректное отображение элементов поверх Canvas/WebGL-рендера.

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

Использование DOM-элементов открывает гибридный подход к разработке интерфейсов в Phaser. Вы можете применять сложные CSS-эффекты, которые сложно или невозможно реализовать на Canvas, и при этом сохранять управление через мощную игровую логику Phaser. Для экспериментов попробуйте: анимировать CSS-свойства (например, filter: hue-rotate()) через Tweens, интегрировать веб-формы или кнопки в игровое меню, использовать CSS-анимации (@keyframes) вместе с твинами Phaser для создания многослойных эффектов.