О чем этот пример
При разработке игры с большим количеством графики управление сотнями отдельных файлов спрайтов превращается в кошмар. Phaser предлагает решение — мультиатласы. Этот метод позволяет объединить несколько файлов атласов (изображение + JSON с координатами) под одним ключом загрузки. В статье разберем, как это работает на практическом примере, и покажем, как упростить работу с графикой, загрузив несколько наборов спрайтов одной командой.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Scene extends Phaser.Scene
{
constructor ()
{
super();
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.path = 'assets/atlas/';
this.load.multiatlas('megaset', 'tp3-multi-atlas.json');
// this.load.image('megaset', 'assets/sprites/beer.png');
this.load.on('filecomplete-multiatlas-megaset', () => {
console.log('multi atlas loaded');
});
}
create ()
{
// This frame is in the 1st atlas file (set0/data0)
this.add.image(0, 0, 'megaset', 'snake').setOrigin(0);
// This frame is in the 2nd atlas file (set1/data1)
this.add.image(0, 100, 'megaset', 'nanoha-taiken-pink').setOrigin(0);
// This frame is in the 3rd atlas file (set2/data2)
// this.add.image(0, 0, 'megaset', 'hello').setOrigin(0); // trimmed
this.add.image(300, 130, 'megaset', 'bunny').setOrigin(0); // un-trimmed
// This frame is in the 4th atlas file (set3/data3)
this.add.image(64, 300, 'megaset', 'contra3').setOrigin(0);
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Scene
}
new Phaser.Game(config);
Что такое мультиатлас и зачем он нужен
Обычный атлас — это один большой PNG-файл, содержащий множество спрайтов, и JSON-файл с координатами каждого из них. Мультиатлас (Multi Atlas) расширяет эту концепцию: это несколько пар PNG+JSON файлов, объединённых в один логический набор внутри Phaser.
Зачем это нужно? Представьте, что у вас есть графика для разных уровней или персонажей, созданная в разных папках или даже разными художниками. Вместо того чтобы загружать каждый атлас отдельно и отслеживать множество ключей, вы можете объединить их в один виртуальный атлас с общим ключом 'megaset'. Это существенно упрощает логику загрузки и доступ к спрайтам в коде.
Практика: загрузка мультиатласа
Загрузка происходит в методе preload(). Ключевой метод — load.multiatlas(). Первый аргумент — общий ключ для всего набора, второй — путь к специальному JSON-файлу, который описывает все отдельные атласы.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.path = 'assets/atlas/';
this.load.multiatlas('megaset', 'tp3-multi-atlas.json');
}
В этом примере задаётся базовый URL и путь. Затем вызывается this.load.multiatlas('megaset', 'tp3-multi-atlas.json'). Phaser загрузит файл tp3-multi-atlas.json, прочитает из него список всех отдельных атласов (set0, set1 и т.д.) и загрузит соответствующие им PNG и JSON файлы. После завершения загрузки всего набора сработает событие filecomplete.
this.load.on('filecomplete-multiatlas-megaset', () => {
console.log('multi atlas loaded');
});
Использование спрайтов из мультиатласа в сцене
После загрузки все спрайты из всех атласов становятся доступны по общему ключу 'megaset'. Неважно, в каком из исходных PNG-файлов находится нужный кадр (frame). Вы обращаетесь к нему, указывая ключ атласа и имя кадра.
create ()
{
// Кадр 'snake' находится в первом файле атласа (set0/data0)
this.add.image(0, 0, 'megaset', 'snake').setOrigin(0);
// Кадр 'nanoha-taiken-pink' находится во втором файле атласа (set1/data1)
this.add.image(0, 100, 'megaset', 'nanoha-taiken-pink').setOrigin(0);
// Кадр 'bunny' находится в третьем файле атласа (set2/data2)
this.add.image(300, 130, 'megaset', 'bunny').setOrigin(0);
// Кадр 'contra3' находится в четвёртом файле атласа (set3/data3)
this.add.image(64, 300, 'megaset', 'contra3').setOrigin(0);
}
Метод this.add.image() принимает координаты X, Y, ключ текстуры (это наш 'megaset') и имя кадра. Phaser сам находит, в каком из загруженных атласов находится кадр с указанным именем, и создаёт изображение. .setOrigin(0) устанавливает точку отсчёта (anchor) в левый верхний угол спрайта, что удобно для позиционирования от нулевых координат.
Структура JSON-файла для мультиатласа
Секрет в структуре файла tp3-multi-atlas.json. Это не обычный JSON от TexturePacker для одного атласа. Это мета-файл, который содержит массив textures. Каждый элемент этого массива — это путь к стандартному JSON-файлу отдельного атласа.
Примерное содержимое такого файла:
on
{
"textures": [
{
"url": "set0.png",
"json": "set0.json"
},
{
"url": "set1.png",
"json": "set1.json"
}
// ... и так далее
]
}
Phaser читает этот файл и для каждого элемента загружает указанные PNG (url) и JSON (json). Все кадры из всех этих атласов индексируются и становятся доступны под ключом, который вы указали первым аргументом в load.multiatlas() (в нашем случае 'megaset').
Плюсы, минусы и особенности
**Плюсы:**
1. **Упрощение кода:** Один ключ загрузки вместо нескольких.
2. **Логическая группировка:** Можно объединить арты по темам (например, 'gui', 'enemies', 'environment') в один мультиатлас.
3. **Удобство для художников:** Разные атласы можно готовить и обновлять независимо.
**Особенности и ограничения:**
1. **Уникальность имён кадров:** Имена кадров (frame names) во всех объединяемых атласах должны быть уникальными. Если в set0 и set1 есть кадр с именем 'hero', произойдёт коллизия, и один из них перезапишет другой.
2. **Загрузка всего набора:** Phaser не поддерживает частичную загрузку или выгрузку отдельных атласов из мультиатласа. Загружается весь набор, указанный в JSON.
3. **Инструменты:** Не все инструменты для создания атласов (например, старые версии TexturePacker) сразу экспортируют нужный для Phaser мультиатлас JSON. Возможно, структуру файла придётся собирать вручную или скриптом.
Что попробовать дальше
Мультиатласы в Phaser — это мощный инструмент для организации графики в больших проектах. Они позволяют сохранить гибкость работы с отдельными файлами атласов, предоставляя при этом единую точку доступа в коде.
**Идеи для экспериментов:**
1. Попробуйте создать мультиатлас вручную, скомбинировав арты из разных источников.
2. Напишите скрипт (например, на Node.js), который автоматически генерирует JSON для мультиатласа, сканируя папку с вашими атласами.
3. Проверьте, как работает кэширование: загрузите мультиатлас, перейдите на другую сцену и создайте спрайты, используя тот же ключ 'megaset' — данные будут взяты из кэша.
