О чем этот пример
Современные игры часто требуют взаимодействия с пользователем через привычные веб-интерфейсы, такие как формы ввода. Phaser 3, благодаря модулю DOM, позволяет легко встраивать HTML-элементы прямо в игровую сцену. Это открывает возможности для создания меню входа, опросов, чатов или кастомизации персонажа без необходимости разрабатывать сложные графические интерфейсы с нуля на канвасе. В этой статье мы разберем, как загрузить, отобразить и обработать данные из HTML-формы, совместив классическую веб-разработку с игровым движком.
Версия 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.html('nameform', 'assets/text/loginform.html');
this.load.image('pic', 'assets/pics/turkey-1985086.jpg');
}
create ()
{
this.add.image(400, 300, 'pic');
const text = this.add.text(10, 10, 'Please login to play', { color: 'white', fontFamily: 'Arial', fontSize: '32px '});
const element = this.add.dom(400, 600).createFromCache('nameform');
element.setPerspective(800);
element.addListener('click');
element.on('click', function (event)
{
if (event.target.name === 'loginButton')
{
const inputUsername = this.getChildByName('username');
const inputPassword = this.getChildByName('password');
// Have they entered anything?
if (inputUsername.value !== '' && inputPassword.value !== '')
{
// Turn off the click events
this.removeListener('click');
// Tween the login form out
this.scene.tweens.add({ targets: element.rotate3d, x: 1, w: 90, duration: 3000, ease: 'Power3' });
this.scene.tweens.add({
targets: element, scaleX: 2, scaleY: 2, y: 700, duration: 3000, ease: 'Power3',
onComplete: function ()
{
element.setVisible(false);
}
});
// Populate the text with whatever they typed in as the username!
text.setText(`Welcome ${inputUsername.value}`);
}
else
{
// Flash the prompt
this.scene.tweens.add({ targets: text, alpha: 0.1, duration: 200, ease: 'Power3', yoyo: true });
}
}
});
this.tweens.add({
targets: element,
y: 300,
duration: 3000,
ease: 'Power3'
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
dom: {
createContainer: true
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка проекта и загрузка ресурсов
Первым делом нужно настроить проект для работы с DOM-элементами. Это делается в конфигурации игры, где необходимо включить опцию createContainer. Без неё система DOM не будет инициализирована.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
dom: {
createContainer: true // Ключевая настройка для работы с HTML
},
scene: Example
};
В методе preload() мы загружаем не только изображение для фона, но и HTML-файл с нашей формой. Важно использовать метод this.load.html(), который загружает и кеширует разметку для последующего использования.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.html('nameform', 'assets/text/loginform.html'); // Загрузка формы
this.load.image('pic', 'assets/pics/turkey-1985086.jpg'); // Загрузка фона
}
Создание и позиционирование DOM-элемента
После загрузки ресурсов, в методе create(), мы можем создать DOM-узел из кеша. Объект this.add.dom() создает специальный игровой объект, который является контейнером для HTML. Метод .createFromCache('nameform') вставляет внутрь этого контейнера загруженную ранее HTML-разметку.
create ()
{
this.add.image(400, 300, 'pic'); // Фоновое изображение
const element = this.add.dom(400, 600).createFromCache('nameform'); // Создание DOM-объекта
}
Изначально элемент помещается за пределами экрана (y=600). Чтобы плавно ввести его в игровую область, используется твин (анимация) для свойства `y`. Это стандартный подход для анимации любых игровых объектов в Phaser, включая DOM-элементы.
this.tweens.add({
targets: element, // Цель анимации — наш DOM-объект
y: 300, // Конечная позиция по Y
duration: 3000, // Длительность 3 секунды
ease: 'Power3' // Функция плавности
});
Обработка событий и данных формы
Чтобы форма стала интерактивной, нужно подписаться на её события. В данном примере мы добавляем слушатель на событие click для всей формы (делегирование событий). Это эффективно, так как обрабатывает клики по любой кнопке внутри элемента.
element.addListener('click');
element.on('click', function (event) {
// event.target — это конкретный HTML-элемент, по которому кликнули
if (event.target.name === 'loginButton') {
// Логика обработки нажатия кнопки Login
}
});
Внутри обработчика мы получаем ссылки на поля ввода по их атрибуту name. Это стандартный DOM-API, доступный через this.getChildByName(), где this внутри функции-обработчика ссылается на DOM-объект Phaser (element).
const inputUsername = this.getChildByName('username');
const inputPassword = this.getChildByName('password');
if (inputUsername.value !== '' && inputPassword.value !== '') {
// Поля заполнены, можно логинить
}
Визуальная обратная связь и анимации
Phaser позволяет добавлять визуальную обратную связь, используя встроенную систему твинов. В примере реализованы два сценария.
Если пользователь ввел логин и пароль, форма анимированно "улетает" со сцены. Обратите внимание на анимацию 3D-вращения через свойство rotate3d — это уникальная возможность для DOM-объектов в Phaser.
// 3D-вращение формы
this.scene.tweens.add({ targets: element.rotate3d, x: 1, w: 90, duration: 3000, ease: 'Power3' });
// Увеличение и смещение вниз
this.scene.tweens.add({
targets: element, scaleX: 2, scaleY: 2, y: 700, duration: 3000,
onComplete: function () { element.setVisible(false); } // Скрытие после анимации
});
Если же поля пусты, мы мигаем текстовой подсказкой, изменяя её свойство alpha (прозрачность). Твин с yoyo: true сначала уменьшает прозрачность до 0.1, а затем возвращает к 1, создавая эффект мерцания.
this.scene.tweens.add({
targets: text, // Текстовый объект с подсказкой
alpha: 0.1,
duration: 200,
ease: 'Power3',
yoyo: true // Возврат к исходному значению
});
Что попробовать дальше
Интеграция HTML-форм через DOM Game Object — мощный инструмент, который стирает границы между игрой и веб-приложением. Вы можете использовать его не только для логина, но и для создания внутриигровых браузеров, сложных HUD-панелей или систем рейтингов. Для экспериментов попробуйте: валидировать email в поле ввода, динамически генерировать форму на основе JSON-конфигурации или привязать анимацию формы к игровым событиям (например, показ формы при проигрыше).
