О чем этот пример
Phaser 3 позволяет интегрировать обычные HTML-элементы прямо в игровое пространство, используя DOM Container. Это открывает уникальные возможности: вы можете добавить сложный текстовый контент, веб-формы или даже целые интерфейсные библиотеки прямо в свою игру, сохраняя при этом все преимущества трансформаций и анимаций Phaser. В этой статье мы разберем, как создать и анимировать DOM-элемент как часть игрового объекта, используя контейнеры и твины.
Версия 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.image('einstein', 'assets/pics/ra-einstein.png');
}
create ()
{
const container = this.add.container(400, 300);
const element = this.add.dom(0, 0, 'div', 'background-color: rgba(255, 255, 0, 0.5); width: 300px; height: 200px; font: 48px Arial; font-weight: bold', 'Phaser 3');
const marker = this.add.rectangle(400, 300, 16, 16, 0xff00ff);
container.add(element);
this.tweens.add({
targets: container,
duration: 3000,
angle: 360,
scaleX: 2,
scaleY: 2,
ease: 'Sine.easeInOut',
loop: -1,
yoyo: true
});
}
}
const config = {
type: Phaser.AUTO,
scale: {
_mode: Phaser.Scale.FIT,
parent: 'phaser-example',
width: 800,
height: 600
},
dom: {
createContainer: true
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка конфигурации и загрузка
Для работы с DOM-элементами в Phaser 3 необходимо активировать соответствующую систему. Это делается в конфигурации игры. Кроме того, в методе preload мы загружаем стандартное изображение для визуального контекста, хотя в данном примере оно не используется.
const config = {
type: Phaser.AUTO,
scale: {
_mode: Phaser.Scale.FIT,
parent: 'phaser-example',
width: 800,
height: 600
},
dom: {
createContainer: true // Ключевой параметр для активации DOM-системы
},
scene: Example
};
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('einstein', 'assets/pics/ra-einstein.png');
}
Создание DOM-элемента и контейнера
В методе create происходит основная магия. Сначала создается this.add.container. Контейнер — это специальный игровой объект, который может группировать другие объекты, и все трансформации применяются к нему как к единому целому.
Затем создается сам DOM-элемент с помощью this.add.dom. Его ключевые параметры: позиция (0,0 относительно контейнера), тег ('div'), инлайн-стили и текстовое содержимое.
Маркер (marker) создается просто как визуальная точка отсчета в центре сцены.
create ()
{
// Создаем контейнер в центре сцены
const container = this.add.container(400, 300);
// Создаем DOM-элемент (div) с желтым фоном, размерами и текстом
const element = this.add.dom(0, 0, 'div', 'background-color: rgba(255, 255, 0, 0.5); width: 300px; height: 200px; font: 48px Arial; font-weight: bold', 'Phaser 3');
// Создаем маркер-прямоугольник в центре сцены для наглядности
const marker = this.add.rectangle(400, 300, 16, 16, 0xff00ff);
// Добавляем DOM-элемент в контейнер
container.add(element);
}
Анимация контейнера с твинами
Phaser Tweens позволяет легко анимировать свойства любых объектов, включая контейнеры. В этом примере мы анимируем контейнер, в который помещен наш DOM-элемент. Это наглядно демонстрирует, что DOM-объект теперь является полноценной частью игрового мира: он вращается и масштабируется вместе с контейнером.
this.tweens.add({
targets: container, // Цель анимации — наш контейнер
duration: 3000, // Длительность анимации в миллисекундах
angle: 360, // Конечный угол поворота (полный оборот)
scaleX: 2, // Масштабирование по оси X
scaleY: 2, // Масштабирование по оси Y
ease: 'Sine.easeInOut', // Функция плавности
loop: -1, // Бесконечный цикл (-1)
yoyo: true // Анимация проигрывается и в обратном направлении
});
Важные особенности и ограничения
Работа с DOM-элементами в Phaser имеет свою специфику.
1. **Производительность:** DOM-операции обычно медленнее, чем отрисовка на Canvas или WebGL. Активно анимируйте не сам DOM-узел, а контейнер Phaser, как в примере.
2. **Стилизация:** Стили задаются строкой, как в инлайн-стилях HTML. Для сложных стилей лучше создать CSS-класс и добавить его к элементу через element.node.classList.add('my-class'), где element.node — это ссылка на нативный DOM-узел.
3. **Взаимодействие:** К DOM-элементу можно добавить слушатели событий через element.addListener('click', ...).
4. **Позиционирование:** Исходная позиция this.add.dom(0, 0, ...) указывается относительно родительского контейнера или сцены. В нашем примере элемент помещен в контейнер, поэтому его позиция (0,0) — это позиция самого контейнера (400,300).
Что попробовать дальше
Интеграция DOM-элементов через this.add.dom и контейнеры — мощный инструмент для создания гибридных интерфейсов в Phaser 3. Вы можете встроить в игру сложные элементы управления, динамический текст с веб-шрифтами или виджеты. Для экспериментов попробуйте: заменить div на input или button, добавить обработчик клика на элемент, анимировать не контейнер, а CSS-свойства самого DOM-узла через твины, или создать сложный интерфейс меню, состоящий из нескольких вложенных DOM-объектов.
