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

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

Версия 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.atlasXML('round', 'assets/atlas/round.png', 'assets/atlas/round.xml');
    }

    create ()
    {
        const atlasTexture = this.textures.get('round');

        const frames = atlasTexture.getFrameNames();

        for (let i = 0; i < frames.length; i++)
        {
            const x = Phaser.Math.Between(0, 800);
            const y = Phaser.Math.Between(0, 600);

            this.add.image(x, y, 'round', frames[i]);
        }
    }
}

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

const game = new Phaser.Game(config);

Что такое текстурный атлас и зачем он нужен

Текстурный атлас — это большое изображение, содержащее множество меньших графических элементов (спрайтов, иконок, частиц). Отдельный файл данных (в нашем случае XML) описывает, какие прямоугольные области этого большого изображения соответствуют какому игровому кадру.

Использование атласа дает два основных преимущества: 1. **Сокращение количества HTTP-запросов.** Браузер загружает один файл изображения и один файл данных вместо десятков или сотен отдельных файлов. 2. **Повышение производительности рендеринга.** Графическому процессору (GPU) проще и быстрее работать с одной текстурой, переключаясь между ее областями, чем постоянно подгружать и выгружать в память множество отдельных текстур.

В Phaser для работы с атласами используется специальный загрузчик.

Настройка базового URL и загрузка атласа

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

Загрузка самого атласа выполняется методом this.load.atlasXML(). Ему нужно передать три аргумента: уникальный ключ текстуры, путь к файлу изображения атласа и путь к файлу данных в формате XML.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.atlasXML('round', 'assets/atlas/round.png', 'assets/atlas/round.xml');
}

В этом коде: - setBaseURL устанавливает корневую часть пути для всех последующих загрузок. - atlasXML загружает атлас с ключом 'round'. Phaser сам загрузит PNG-изображение и XML-файл, а затем автоматически их свяжет и обработает.

Получение кадров и создание изображений

После успешной загрузки в методе create() мы можем начать использовать наш атлас. Сначала нужно получить ссылку на саму текстуру по её ключу.

Затем, чтобы понять, какие кадры (спрайты) доступны внутри атласа, мы получаем массив их имён.

const atlasTexture = this.textures.get('round');
const frames = atlasTexture.getFrameNames();

Теперь, имея список всех кадров, мы можем в цикле создать игровые объекты. В примере для каждого кадра генерируются случайные координаты на экране, и создаётся объект типа Image.

for (let i = 0; i < frames.length; i++)
{
    const x = Phaser.Math.Between(0, 800);
    const y = Phaser.Math.Between(0, 600);
    this.add.image(x, y, 'round', frames[i]);
}

Критически важны параметры, передаваемые в this.add.image(): 1. x, y — координаты позиции объекта. 2. 'round' — ключ текстуры (атласа), из которой будет взят кадр. 3. frames[i] — имя конкретного кадра внутри этого атласа. Именно этот параметр указывает движку, какую область большого PNG-файла использовать для отрисовки данного объекта.

Конфигурация и запуск игры

Код примера завершается стандартной для Phaser 3 конфигурацией и созданием игрового экземпляра. В конфиге указывается тип рендерера, размеры холста, родительский HTML-элемент и стартовая сцена.

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

const game = new Phaser.Game(config);

Когда игра запускается (new Phaser.Game(config)), Phaser инициализирует движок, создает канвас внутри элемента с id='phaser-example' и запускает жизненный цикл указанной сцены Example: сначала preload(), затем create().

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

Загрузка и использование текстурного атласа через atlasXML — это простой и мощный способ организовать графику вашей игры. Вы освоили базовый пайплайн: от предзагрузки связки PNG+XML до получения списка кадров и их отрисовки в случайных позициях. Для экспериментов попробуйте: 1. Создать свой атлас с помощью инструментов вроде TexturePacker или Shoebox и загрузить его. 2. Использовать кадры атласа не для статичных Image, а для создания спрайтов с физикой через this.physics.add.image. 3. На основе кадров из атласа создать анимацию, используя this.anims.create(). 4. Загрузить несколько разных атласов и переключаться между их кадрами в зависимости от состояния игрока или уровня.