О чем этот пример
В процессе разработки игры количество ресурсов — спрайтов, звуков, данных — быстро растёт. Управлять загрузкой каждого файла по отдельности становится неудобно и громоздко. Phaser предоставляет мощный инструмент — загрузку через JSON-пакеты (File Packs). Этот подход позволяет организовать ассеты в логические группы и загружать их одной строкой кода, что делает код чище, а процесс разработки — быстрее и надёжнее. В этой статье мы разберём, как работает загрузчик Phaser с пакетами, на конкретном примере. Вы научитесь структурировать свои ресурсы и эффективно подгружать только нужные их части в разные сцены игры.
Версия 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('pack1', 'assets/loader-tests/pack1.json', 'test2');
}
create ()
{
this.add.image(400, 300, 'TEST2.donuts');
this.add.image(500, 300, 'TEST2.ayu');
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое File Pack и зачем он нужен
File Pack — это JSON-файл, который описывает группу ресурсов (изображения, аудио, атласы и т.д.). Вместо того чтобы вызывать this.load.image(), this.load.audio() для каждого файла в коде сцены, вы описываете все эти вызовы в отдельном конфигурационном файле.
Это даёт несколько преимуществ:
* **Организация:** Ассеты можно группировать по сценам, уровням или типам (например, «главное меню», «персонажи», «звуки UI»).
* **Переиспользование:** Один пакет можно загрузить в разных сценах.
* **Читаемость кода:** Метод preload() сцены становится лаконичным и понятным.
* **Гибкость:** Можно загружать не весь пакет целиком, а только выбранную его часть (как в нашем примере).
Разбираем структуру примера: preload()
Давайте посмотрим, как в примере реализована загрузка части пакета.
Сначала в preload() мы настраиваем базовый URL, от которого будут рассчитываться пути ко всем файлам в этом пакете. Это удобно, если все ваши ресурсы лежат в одном корне.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
Затем происходит ключевой вызов — загрузка пакета. Метод load.pack() принимает три аргумента.
this.load.pack('pack1', 'assets/loader-tests/pack1.json', 'test2');
1. **Ключ пакета ('pack1'):** Уникальный идентификатор для этого пакета внутри загрузчика Phaser.
2. **URL пакета ('assets/loader-tests/pack1.json'):** Путь к JSON-файлу с описанием пакета. Путь строится относительно базового URL.
3. **Ключ данных ('test2'):** Самый важный для нашего примера параметр. Он указывает, какую именно *часть* (section) из JSON-пакета нужно загрузить. Если этот параметр опущен, будет загружен весь пакет.
Создание сцены и использование загруженных ассетов
После успешной загрузки пакета в методе create() мы можем использовать текстуры. Обратите внимание на имена ключей (keys), по которым к ним обращаются.
this.add.image(400, 300, 'TEST2.donuts');
this.add.image(500, 300, 'TEST2.ayu');
Ключи имеют составной формат: 'TEST2.donuts' и 'TEST2.ayu'. Здесь 'TEST2' — это как раз тот самый ключ данных (dataKey), который мы передали в load.pack(). А 'donuts' и 'ayu' — это имена файлов, определённые внутри соответствующей секции JSON-пакета.
Такой подход позволяет иметь в одном большом пакете несколько независимых групп ассетов и загружать их по мере необходимости, избегая конфликтов имён.
Как может выглядеть JSON-пакет (pack1.json)
Хотя в примере сам файл пакета не показан, мы можем предположить его структуру, основываясь на коде. Вероятно, он содержит несколько секций, одна из которых имеет ключ 'test2'.
{
"test1": [
{ "type": "image", "key": "logo", "url": "assets/logo.png" }
],
"test2": [
{ "type": "image", "key": "donuts", "url": "assets/donuts.png" },
{ "type": "image", "key": "ayu", "url": "assets/ayu.png" }
],
"audioPack": [
{ "type": "audio", "key": "theme", "url": ["audio/main.mp3", "audio/main.ogg"] }
]
}
Каждая секция (например, 'test2') — это массив объектов. Каждый объект описывает один файл: его тип (type), ключ для использования в коде (key) и путь к файлу (url). Phaser на основе типа ('image', 'audio', 'atlas' и др.) знает, какой метод загрузки использовать.
Что попробовать дальше
Использование JSON-пакетов — это профессиональный подход к управлению ресурсами в Phaser. Он отделяет конфигурацию данных от логики игры, что особенно ценно в больших проектах. Вы можете легко добавлять новые ассеты, редактируя JSON-файл, не трогая код сцен.
**Идеи для экспериментов:**
1. Создайте пакет с разными типами ассетов (изображения, звуки, атласы спрайтов) и загрузите его целиком, не указывая ключ данных.
2. Напишите скрипт, который будет автоматически генерировать JSON-пакет на основе файлов в вашей папке assets.
3. Реализуйте прогрессивную загрузку: загрузите пакет с ресурсами для главного меню, а после входа в игру — динамически загрузите пакет с ресурсами для первого уровня, используя тот же метод load.pack().
