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

В разработке игр часто требуется динамический интерфейс: сложные таблицы рекордов, интерактивные меню или информационные панели с живыми данными. Рендерить их вручную на канвасе — долго и сложно. Загрузка HTML в текстуру (`htmlTexture`) решает эту проблему, позволяя использовать всю мощь HTML и CSS для создания элементов, а затем встраивать их в игровой мир как обычные спрайты. Это открывает путь к созданию сложных UI, которые можно анимировать и трансформировать средствами движка.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    image;

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.htmlTexture('test1', 'assets/html/test1.html', 512, 512);
    }

    create ()
    {
        this.image = this.add.image(400, 300, 'test1').setOrigin(0);
    }

    update ()
    {
        this.image.rotation += 0.01;
    }
}

const config = {
    type: Phaser.CANVAS,
    width: 800,
    height: 600,
    backgroundColor: '#efefef',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Зачем это нужно? Суть метода

Метод load.htmlTexture — это мост между веб-технологиями и игровым движком. Вместо того чтобы рисовать сложный интерфейс пиксель за пикселем, вы создаёте его в HTML и CSS, как обычную веб-страницу. Phaser загружает этот HTML-файл, рендерит его в заданном разрешении в «невидимый» браузерный контекст и сохраняет результат как обычную текстуру (изображение). Эту текстуру можно использовать для спрайтов, изображений, частиц — для всего, что поддерживает текстуры. Таким образом, вы получаете статичный «снимок» вашего HTML-контента, встроенный в игру. Это идеально для элементов, которые не должны меняться каждый кадр, но требуют сложного вёрстки (например, блок с описанием предмета, стилизованная кнопка или таблица).

Настройка загрузчика и загрузка HTML

Всё начинается в методе preload(). Первым делом полезно задать базовый URL для загрузчиков, особенно если ваши ассеты лежат в удалённом репозитории или конкретной папке. Это избавляет от необходимости прописывать полный путь к каждому файлу.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');

Затем вызывается ключевой метод load.htmlTexture(). Он принимает четыре аргумента: ключ текстуры (по которому вы будете на неё ссылаться), путь к HTML-файлу, а также ширину и высоту результирующей текстуры. Эти размеры определяют «холст», на котором будет отрисован ваш HTML.

this.load.htmlTexture('test1', 'assets/html/test1.html', 512, 512);

Важно: HTML-файл может содержать ссылки на CSS-файлы, изображения, шрифты — всё это будет загружено и отображено при рендеринге текстуры. Процесс загрузки асинхронный, как и для других ассетов.

Создание и использование спрайта с HTML-текстурой

После загрузки текстура доступна в кеше под ключом 'test1' и используется абсолютно так же, как любая другая текстура. В методе create() мы создаём игровой объект Image, передавая ему координаты и ключ этой текстуры.

this.image = this.add.image(400, 300, 'test1').setOrigin(0);

Обратите внимание на setOrigin(0). Это устанавливает точку вращения и выравнивания спрайта в его левый верхний угол. Это часто удобно для работы с UI-элементами. Теперь this.image — это обычный спрайт Phaser, который содержит отрендеренный HTML-контент.

Анимация и обновление

Поскольку мы работаем с обычным игровым объектом, к нему применимы все стандартные трансформации и свойства Phaser: положение, масштаб, вращение, прозрачность, смещение текстуры и т.д. В примере в методе update() объект плавно вращается, демонстрируя, что это динамическая часть игрового мира.

this.image.rotation += 0.01;

Это вращение применяется ко всему отрендеренному HTML-блоку как к единому целому. Вы можете аналогично двигать его по экрану, анимировать масштаб или применять любые другие эффекты, доступные для Image.

Конфигурация игры и важные ограничения

Для работы с htmlTexture в конфигурации игры **обязательно** должен быть указан type: Phaser.CANVAS. Рендеринг HTML в текстуру не работает в режиме WebGL (Phaser.WEBGL). Это ключевое техническое ограничение.

const config = {
    type: Phaser.CANVAS,
    width: 800,
    height: 600,
    backgroundColor: '#efefef',
    parent: 'phaser-example',
    scene: Example
};

Также помните, что текстура создаётся один раз в момент загрузки. Если содержимое исходного HTML-файла изменится во время выполнения игры, текстура автоматически не обновится. Для динамического контента потребуется более сложный подход с перезагрузкой.

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

Загрузка HTML в текстуру — это мощный инструмент для быстрого прототипирования и создания сложных статичных UI-элементов в Phaser. Вы используете знакомые веб-технологии для вёрстки, а движок превращает результат в часть игрового мира. Для экспериментов попробуйте: создать текстуру с HTML-формой, использовать CSS-анимации внутри HTML перед рендерингом в текстуру, или менять текстуру в runtime, подгружая разные HTML-файлы в ответ на действия игрока. Это откроет новые возможности для нестандартных интерфейсов.