О чем этот пример
Phaser — это не только про красивые анимации на экране. С помощью режима `Phaser.HEADLESS` вы можете запускать игровую логику, физику и системы событий без визуального рендеринга. Это открывает двери для создания серверных симуляций, автономных ботов, тестирования игрового баланса или предварительной обработки данных — всё это без нагрузки на графический процессор и в средах, где нет DOM или WebGL, например, в Node.js.
Версия 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('pic', 'assets/pics/baal-loader.png');
}
create ()
{
const pic = this.add.image(400, 300, 'pic');
this.tweens.add({
targets: pic,
angle: 360,
repeat: -1
});
}
}
const config = {
type: Phaser.HEADLESS,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Что такое headless-режим?
В обычном режиме Phaser создаёт canvas-элемент и использует WebGL или Canvas API для отрисовки кадров. В headless-режиме (type: Phaser.HEADLESS) этот этап рендеринга полностью пропускается. Игра работает "вслепую", но все её внутренние системы (сцены, загрузка, таймеры, твины, физика, если она подключена) функционируют как обычно.
Это позволяет запускать экземпляр Phaser.Game там, где нет браузера или графического контекста. Ключевой параметр type в конфиге игры управляет этим поведением.
Анализ примера кода
Рассмотрим предоставленный пример. Он определяет сцену с базовым жизненным циклом: предзагрузка ресурса и создание игровых объектов.
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('pic', 'assets/pics/baal-loader.png');
}
create ()
{
const pic = this.add.image(400, 300, 'pic');
this.tweens.add({
targets: pic,
angle: 360,
repeat: -1
});
}
}
В методе preload() задаётся базовый URL и загружается одно изображение. Важно понимать: в headless-режиме загрузка ресурсов (this.load.image) всё равно происходит, но текстура не будет создана или загружена в GPU. Система загрузки завершится успешно, имитируя процесс.
В методе create() создаётся игровой объект Image с помощью this.add.image. Несмотря на отсутствие рендерера, объект будет корректно добавлен в сцену и займёт своё место в её древовидной структуре.
Далее к объекту применяется твин (анимация) через this.tweens.add. Этот твин будет бесконечно вращать изображение, изменяя его свойство angle. Система твинов будет обновляться на каждом кадре игры, даже если визуально мы этого не видим.
Конфигурация headless-игры
Магия происходит в объекте конфигурации. Всё, что нужно — указать type: Phaser.HEADLESS.
const config = {
type: Phaser.HEADLESS,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Параметры width и height по-прежнему важны. Они определяют виртуальное игровое пространство, систему координат и, например, зону действия камеры. Параметр parent в этом режиме часто игнорируется, так как не требуется привязка к DOM-элементу. После создания экземпляра игры (new Phaser.Game(config)) немедленно запускается игровой цикл.
Практическое применение и ограничения
**Для чего это использовать?** * **Серверная логика:** Запуск симуляций боя, генерация логов для аналитики. * **Юнит-тестирование:** Проверка корректности работы сложных скриптов и взаимодействий объектов. * **Боты и AI:** Обучение и выполнение AI в изолированном, контролируемом окружении. * **Генерация контента:** Предварительный расчёт траекторий, позиций спавна и т.д.
**Что не будет работать?**
* Любые операции, зависящие от рендерера: отрисовка, пост-обработка, работа с пиксельными данными canvas.
* Ввод с мыши или клавиатуры (но его можно эмулировать, напрямую вызывая методы input).
* Загрузка реальных текстур в видеопамять. Система загрузки выполнится, но графические ассеты будут "заглушками".
Для работы в Node.js потребуется установить пакет phaser и, возможно, реализовать полифиллы для некоторых Web API, которые Phaser ожидает найти (например, requestAnimationFrame).
Что попробовать дальше
Headless-режим Phaser — мощный инструмент, который выводит фреймворк за рамки клиентского браузерного рендеринга. Он позволяет использовать отлаженную и богатую архитектуру Phaser для "невидимых" вычислительных задач. Для экспериментов попробуйте подключить модуль физики Arcade (physics: { default: 'arcade' }) в конфиге и запустить симуляцию падения сотни тел, логируя их позиции, или создайте сцену, которая генерирует JSON-карту уровня на основе алгоритмических правил.
