О чем этот пример
Загрузка десятков изображений, звуков и данных вручную превращает метод `preload` в хаос. Phaser предлагает элегантное решение — файловые пакеты (File Packs). Они позволяют вынести описание всех ресурсов в отдельный 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('pack1', 'assets/loader-tests/pack1.json', 'test1');
}
create ()
{
this.add.image(400, 300, 'taikodrummaster');
this.add.image(400, 500, 'sukasuka-chtholly');
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое файловый пакет (File Pack)?
Файловый пакет — это JSON-файл, который описывает список ресурсов (изображения, аудио, атласы и т.д.) для загрузки. Вместо того чтобы вызывать множество методов this.load.image() или this.load.audio() внутри сцены, вы один раз указываете загрузчику на этот пакет. Это особенно полезно для больших проектов, где ресурсы логически сгруппированы (например, по уровням или персонажам).
Phaser загружает пакет как обычный файл, а затем парсит его содержимое, автоматически добавляя все указанные в нем ресурсы в очередь загрузки.
Разбор примера кода: от настройки до создания
Рассмотрим ключевые строки из предоставленного примера. Вся магия начинается в методе preload.
Сначала мы задаем базовый URL для всех загружаемых ресурсов. Это означает, что все последующие пути будут вычисляться относительно этого адреса.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
Затем мы загружаем сам пакет. Метод load.pack принимает три аргумента: ключ пакета, путь к JSON-файлу и, опционально, ключ данных внутри JSON (если файл содержит несколько пакетов).
this.load.pack('pack1', 'assets/loader-tests/pack1.json', 'test1');
В данном случае загрузчик найдет файл по адресу, сформированному из базового URL и переданного пути: https://raw.githubusercontent.com/phaserjs/examples/master/public/assets/loader-tests/pack1.json. После загрузки JSON-файла он возьмет из него раздел с ключом test1 и начнет загружать все ресурсы, описанные там.
После успешной загрузки всех ресурсов в методе create мы можем использовать их по их ключам, как если бы они были загружены обычным способом.
this.add.image(400, 300, 'taikodrummaster');
this.add.image(400, 500, 'sukasuka-chtholly');
Структура JSON-пакета
Как же выглядит файл pack1.json? Phaser ожидает определенной структуры. Вот примерный вид, соответствующий нашему коду:
on
{
"test1": {
"files": [
{
"type": "image",
"key": "taikodrummaster",
"url": "assets/loader-tests/taikodrummaster.png"
},
{
"type": "image",
"key": "sukasuka-chtholly",
"url": "assets/loader-tests/sukasuka-chtholly.png"
}
]
}
}
Ключ test1 на верхнем уровне — это тот самый ключ данных, который мы передали третьим параметром в load.pack. Внутри него находится массив files. Каждый элемент массива — это объект с обязательными полями:
* type: Тип ресурса (image, audio, atlas, json и др.).
* key: Уникальный строковый ключ, по которому вы будете обращаться к ресурсу в игре.
* url: Путь к файлу. Он будет склеен с базовым URL, заданным через setBaseURL.
Таким образом, пакет — это просто декларативный список того, что нужно загрузить.
Почему это эффективно? Преимущества подхода
1. **Чистота кода:** Метод preload вашей сцены остается компактным и читаемым. Вся информация о ресурсах вынесена во внешний файл.
2. **Удобство управления:** Добавить, удалить или изменить путь к ресурсу можно в одном JSON-файле, не копаясь в логике сцены.
3. **Разделение ответственности:** Художники или дизайнеры могут подготавливать и обновлять пакеты ресурсов, не требуя глубоких правок в коде программиста.
4. **Гибкость:** Вы можете иметь несколько пакетов (например, pack-ui.json, pack-level1.json, pack-sounds.json) и загружать их по мере необходимости, реализуя прогрессивную загрузку контента.
Типичные ошибки и как их избежать
// ОШИБКА: Ключ в пакете не совпадает с ключом, используемым в create.
// В пакете ключ 'hero', а в коде используется 'player'.
this.add.image(100, 100, 'player'); // Texture 'player' not found!
* **Несоответствие ключей:** Самая частая проблема. Убедитесь, что ключ key в JSON-пакете в точности совпадает со строкой, которую вы передаете при создании объекта (например, в this.add.image(x, y, 'key')).
* **Ошибки в пути (URL):** Phaser не сможет загрузить ресурс, если итоговый URL окажется битым. Проверьте, что комбинация setBaseURL и url из пакета ведет на существующий файл.
* **Отсутствующий ключ данных:** Если вы передаете третий параметр в load.pack (как 'test1' в нашем примере), убедитесь, что этот ключ существует на верхнем уровне вашего JSON-файла. Если пакет один, можно передать null, и загрузчик возьмет корневой объект.
// Если в JSON нет вложенности с ключом 'myLevel'.
this.load.pack('pack1', 'assets/pack.json', 'myLevel'); // Ошибка загрузки данных.
Что попробовать дальше
Использование JSON-пакетов — это профессиональный подход к организации ресурсов в Phaser, который масштабируется вместе с вашим проектом. Он превращает загрузку из нагромождения вызовов в декларативную и легко редактируемую конфигурацию.
**Идеи для экспериментов:**
1. Создайте пакет, который загружает не только изображения, но и звуковые файлы (type: "audio") и JSON-данные (type: "json").
2. Реализуйте механизм смены локализации: подготовьте разные пакеты для русского и английского языков и загружайте нужный в зависимости от выбора игрока.
3. Напишите простой инструмент на JavaScript, который автоматически генерирует JSON-пакет, сканируя папку с ресурсами вашей игры.
