О чем этот пример
Загрузка анимаций из внешних JSON-файлов — это мощный подход к организации ресурсов в Phaser. Он позволяет отделить данные анимаций (кадры, частоту) от логики игры, что упрощает работу художникам и аниматорам. В этой статье разберем пример загрузки и воспроизведения нескольких анимаций из одного JSON-файла, что особенно полезно для проектов с большим количеством анимационных клипов.
Версия 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.animation('gemData', 'assets/animations/gems.json');
this.load.atlas('gems', 'assets/tests/columns/gems.png', 'assets/tests/columns/gems.json');
}
create ()
{
this.add.text(400, 32, 'Animations from Animation JSON file', { color: '#00ff00' }).setOrigin(0.5, 0);
this.add.sprite(400, 200, 'gems').play('diamond');
this.add.sprite(400, 300, 'gems').play('prism');
this.add.sprite(400, 400, 'gems').play('ruby');
this.add.sprite(400, 500, 'gems').play('square');
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Зачем выносить анимации в JSON?
Встроенное создание анимаций через this.anims.create() прямо в коде сцены подходит для прототипов. Однако для production-проектов такой подход становится громоздким. Храня определения анимаций в JSON, вы достигаете нескольких целей:
* **Разделение ответственности:** Аниматоры могут редактировать файлы данных, не касаясь кода. * **Упрощение обновлений:** Можно заменить один файл, чтобы обновить все анимации объекта. * **Динамическая загрузка:** Загружайте пакеты анимаций по мере необходимости, экономя первоначальный объем загрузки.
Пример в статье демонстрирует базовый, но эффективный паттерн для работы с таким подходом.
Загрузка данных анимации и текстурного атласа
Вся подготовка происходит в методе preload(). Ключевой момент — загрузка двух связанных ресурсов: файла с данными анимаций и самого атласа спрайтов, на который эти данные ссылаются.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.animation('gemData', 'assets/animations/gems.json');
this.load.atlas('gems', 'assets/tests/columns/gems.png', 'assets/tests/columns/gems.json');
}
* `this.load.animation()` загружает JSON-файл и автоматически регистрирует все анимации, описанные в нем, в глобальный менеджер анимаций (`this.anims`). Первый параметр — произвольный ключ, второй — путь к данным.
* `this.load.atlas()` загружает изображение-атлас (`gems.png`) и файл с координатами кадров внутри него (`gems.json`). Ключ `'gems'` будет использоваться для создания спрайтов.
Важно, что файлы gems.json (для атласа) и gems.json (для анимаций) — это разные файлы, хотя и имеют схожие имена в этом примере.
Создание спрайтов и запуск анимаций
После загрузки в методе create() анимации уже доступны в системе. Нам остается только создать спрайты из загруженного атласа и проиграть на них нужные клипы.
create ()
{
this.add.text(400, 32, 'Animations from Animation JSON file', { color: '#00ff00' }).setOrigin(0.5, 0);
this.add.sprite(400, 200, 'gems').play('diamond');
this.add.sprite(400, 300, 'gems').play('prism');
this.add.sprite(400, 400, 'gems').play('ruby');
this.add.sprite(400, 500, 'gems').play('square');
}
* Каждый вызов this.add.sprite() создает новый спрайт, использующий текстуру с ключом 'gems'.
* Метод .play() сразу запускает анимацию. Имена анимаций ('diamond', 'prism' и т.д.) должны точно соответствовать тем, что объявлены в загруженном JSON-файле. Phaser сам находит созданную ранее анимацию по этому имени и применяет ее к спрайту.
Структура JSON-файла с анимациями
Чтобы данный пример работал, файл gems.json (с данными анимации) должен иметь специфическую структуру, понятную загрузчику Phaser. Вот примерный вид такого файла:
{
"anims": [
{
"key": "diamond",
"frames": [
{ "key": "gems", "frame": "diamond_01" },
{ "key": "gems", "frame": "diamond_02" }
],
"frameRate": 8,
"repeat": -1
},
{
"key": "prism",
"frames": [ { "key": "gems", "frame": "prism_01" } ],
"frameRate": 1
}
]
}
* key: Уникальное имя анимации, используемое в методе .play().
* frames: Массив объектов, каждый из которых ссылается на key атласа и frame — имя конкретного кадра внутри атласа (эти имена определены в gems.json атласа).
* frameRate: Скорость воспроизведения.
* repeat: Количество повторений (-1 для бесконечного цикла).
Именно в этом формате Phaser ожидает получить данные от this.load.animation().
Что попробовать дальше
Использование внешних JSON-файлов для анимаций делает код чище, а процесс разработки — гибче. Для экспериментов попробуйте:
1. Изменить частоту кадров (frameRate) или порядок кадров в JSON-файле и увидеть, как это мгновенно отразится в игре без перезаписи кода.
2. Загружать разные JSON-файлы с анимациями для разных уровней или персонажей по требованию.
3. Скомбинировать этот подход с созданием анимаций в коде для особых, динамически генерируемых эффектов.
