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

В современных играх часто требуется загружать и обрабатывать структурированные данные, например, диалоги, конфигурацию уровней или списки объектов. XML — это проверенный формат для таких задач. В этой статье вы узнаете, как загрузить XML-файл в Phaser, распарсить его с помощью стандартного DOM API и отобразить результат в игре, используя мощный DOM-контейнер. Этот подход отлично подходит для создания внутриигровых меню, журналов или любого интерфейса, требующего работы с текстовыми данными.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('logo', 'assets/sprites/phaser.png');
        this.load.xml('data', 'assets/loader-tests/test.xml');
    }

    create ()
    {
        this.add.image(8, 8, 'logo').setOrigin(0);

        const catalog = this.cache.xml.get('data');

        const books = catalog.getElementsByTagName('book');

        let data = '';

        Array.from(books).forEach(book => {

            const title = book.getElementsByTagName('title')[0].childNodes[0].nodeValue;
            const author = book.getElementsByTagName('author')[0].childNodes[0].nodeValue;

            data = data.concat(`${title} by ${author}\n`);
        });

        this.add.dom(400, 300, 'div', 'background-color: rgba(0, 0, 80); width: 600px; height: 500px; font: 12px Courier; color: white; overflow: hidden', data);
    }
}

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

const game = new Phaser.Game(config);

Настройка загрузки XML и изображений

В фазе preload мы подготавливаем все необходимые ресурсы для сцены. Ключевой момент — использование методов this.load.xml и this.load.image. Установка базового URL упрощает загрузку из удалённого источника.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('logo', 'assets/sprites/phaser.png');
    this.load.xml('data', 'assets/loader-tests/test.xml');
}

Доступ к закэшированным XML-данным

После загрузки данные автоматически помещаются в кеш. В фазе create мы извлекаем их с помощью this.cache.xml.get. Возвращаемый объект — это стандартный XMLDocument, с которым можно работать как с обычным DOM в браузере.

create ()
{
    this.add.image(8, 8, 'logo').setOrigin(0);
    const catalog = this.cache.xml.get('data');

Парсинг данных с помощью DOM API

Используя методы getElementsByTagName, мы получаем коллекцию элементов book. Проходим по ней, извлекая текстовые значения из дочерних элементов title и author. Обратите внимание на использование childNodes[0].nodeValue для получения текстового содержимого внутри тега.

const books = catalog.getElementsByTagName('book');
    let data = '';
    Array.from(books).forEach(book => {
        const title = book.getElementsByTagName('title')[0].childNodes[0].nodeValue;
        const author = book.getElementsByTagName('author')[0].childNodes[0].nodeValue;
        data = data.concat(`${title} by ${author}\n`);
    });

Создание DOM-контейнера для отображения

Phaser предоставляет мощный метод this.add.dom для встраивания HTML-элементов прямо на игровой канвас. Мы создаём div, задаём ему стили (фон, размеры, шрифт) и помещаем внутрь сформированную текстовую строку. Важно: для работы метода в конфигурации игры должен быть включён dom.createContainer: true.

this.add.dom(400, 300, 'div', 'background-color: rgba(0, 0, 80); width: 600px; height: 500px; font: 12px Courier; color: white; overflow: hidden', data);
}

Конфигурация игры с поддержкой DOM

Основная конфигурация игры должна явно указывать на необходимость создания контейнера для DOM-элементов. Без этого параметра this.add.dom не будет работать.

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    dom: {
        createContainer: true
    },
    scene: Example
};
const game = new Phaser.Game(config);

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

Вы научились загружать, парсить и визуализировать XML-данные в Phaser, комбинируя возможности загрузчика, кеша и DOM API. Это открывает путь к созданию сложных текстовых интерфейсов, интерактивных диалоговых систем или редакторов уровней на основе данных. Для экспериментов попробуйте: загружать XML с описанием предметов инвентаря и создавать для них иконки, реализовать постраничный вывод в DOM-контейнере или анимировать появление текста с помощью CSS-стилей, доступных для dom-объектов.