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

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

Версия 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.pack('pack', 'assets/loader-tests/pack5.json');
    }

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

        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, 'megaset', frames[i]);
        }
    }
}

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

const game = new Phaser.Game(config);

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

Первым шагом является конфигурация базового пути для всех загружаемых ресурсов. Это позволяет указывать относительные пути внутри пакетного файла, что делает код чище и удобнее для переноса проекта.

Затем мы загружаем сам пакет, используя метод load.pack. Первый аргумент — это ключ загрузки, второй — путь к JSON-файлу с описанием пакета.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.pack('pack', 'assets/loader-tests/pack5.json');

Получение атласа и списка кадров

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

Метод textures.get() возвращает объект текстуры. У этого объекта есть метод getFrameNames(), который извлекает массив строк с именами всех отдельных кадров (спрайтов), содержащихся внутри атласа.

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

Динамическое создание изображений из кадров атласа

Имея массив имен кадров, мы можем в цикле создавать игровые объекты Image. Для добавления визуального разнообразия позиция каждого изображения задается случайным образом с помощью Phaser.Math.Between.

Метод add.image() принимает четыре аргумента: координаты X и Y, ключ текстуры (атласа) и имя конкретного кадра из этого атласа. В результате на сцене появляются все спрайты из атласа в случайных позициях.

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, 'megaset', frames[i]);
}

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

Весь функционал сцены работает в рамках общей конфигурации игры. В объекте config мы определяем базовые настройки, такие как тип рендерера, размеры холста и связываем сцену с игровым экземпляром.

Запуск игры происходит путем создания нового экземпляра Phaser.Game с переданной конфигурацией.

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

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

Использование JSON-паков для загрузки текстурных атласов — это мощный и эффективный паттерн в Phaser. Он не только оптимизирует процесс загрузки, но и централизует управление ресурсами. Для экспериментов попробуйте

  1. создать свой собственный JSON-пак с атласом и другими типами ресурсов (звуками, JSON-данными)
  2. анимировать созданные изображения, добавляя к ним физические тела или твины
  3. реализовать логику выборочной отрисовки кадров в зависимости от игровых событий