О чем этот пример
В разработке игр важно не только создать красивые ассеты, но и эффективно их загружать. Мультиатласы (Multi-Atlas) — это продвинутый формат упаковки текстур, который позволяет разделить большой набор спрайтов на несколько файлов изображений, сохранив при этом единый файл данных с координатами. Этот подход особенно полезен для уменьшения времени загрузки и управления памятью при работе с большими коллекциями графики, например, в сложных анимациях или интерфейсах. В этой статье мы разберем, как загружать и использовать мультиатласы в Phaser на примере с форматом WebP, что даст вам практический инструмент для оптимизации ваших игровых проектов.
Версия 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.multiatlas('game', 'assets/atlas/multi-webp.json', 'assets/atlas/');
}
create ()
{
const atlasTexture = this.textures.get('game');
const frames = atlasTexture.getFrameNames();
for (let i = 0; i < frames.length; i++)
{
const x = Phaser.Math.Between(0, 1024);
const y = Phaser.Math.Between(0, 768);
this.add.image(x, y, 'game', frames[i]);
}
}
}
const config = {
type: Phaser.AUTO,
width: 1024,
height: 768,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое мультиатлас и зачем он нужен?
Традиционный текстурный атлас — это один большой файл изображения (PNG, JPEG, WebP) и один JSON-файл с координатами (data file). Мультиатлас расширяет эту концепцию: один JSON-файл данных может ссылаться на несколько файлов изображений. Это решает несколько проблем:
- **Оптимизация загрузки**: Браузер может параллельно загружать несколько небольших файлов вместо одного огромного, что часто быстрее. - **Управление памятью**: Вы можете выгружать неиспользуемые части атласа (например, текстур для уровня 2, пока игрок на уровне 1). - **Гибкость**: Разные типы ассетов (персонаж, окружение, UI) можно хранить в отдельных файлах, но использовать как единый атлас через общий ключ.
В примере используется формат WebP — современный формат сжатия, обеспечивающий высокое качество при малом размере файла.
Настройка базового URL и загрузка мультиатласа
Загрузка ресурсов в Phaser происходит в методе preload сцены. Первым делом мы задаем базовый URL для всех последующих загрузок через this.load.setBaseURL. Это удобно, если все ваши ассеты лежат в одной корневой папке на сервере.
Затем мы загружаем сам мультиатлас с помощью метода this.load.multiatlas. Важно передать ему три аргумента.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.multiatlas('game', 'assets/atlas/multi-webp.json', 'assets/atlas/');
- 'game' — это уникальный ключ (текстурный ключ), по которому мы будем обращаться к загруженному атласу в игре.
- 'assets/atlas/multi-webp.json' — путь к JSON-файлу данных атласа относительно базового URL.
- 'assets/atlas/' — путь к папке, где лежат файлы изображений (.webp), на которые ссылается JSON. Phaser автоматически подставит этот путь к именам файлов из JSON.
Структура JSON-файла для мультиатласа
Чтобы Phaser корректно загрузил мультиатлас, JSON-файл должен иметь специфическую структуру. В отличие от обычного атласа, в свойстве textures находится массив объектов, каждый из которых описывает отдельный файл изображения.
Пример структуры (сокращенно):
{
"textures": [
{
"image": "game-0.webp", // Имя файла изображения
"format": "RGBA8888",
"size": {"w": 512, "h": 512},
"scale": 1,
"frames": [
// ... массив фреймов с координатами для этого файла
]
},
{
"image": "game-1.webp",
// ... данные для второго файла
}
]
}
Метод multiatlas парсит этот файл, загружает все указанные изображения (game-0.webp, game-1.webp и т.д.) и создает в системе текстур (this.textures) единую текстуру с ключом 'game', объединяя все фреймы из всех файлов.
Доступ к текстуре и создание изображений
После загрузки в методе create мы можем начать использовать атлас. Сначала получаем ссылку на объект текстуры по ее ключу.
const atlasTexture = this.textures.get('game');
Объект atlasTexture содержит всю информацию об атласе. Метод getFrameNames() возвращает массив строк с именами всех доступных фреймов (например, ['background', 'player_idle_01', 'enemy_walk_02']).
Затем пример в цикле создает несколько изображений на сцене, используя случайные координаты.
const frames = atlasTexture.getFrameNames();
for (let i = 0; i < frames.length; i++)
{
const x = Phaser.Math.Between(0, 1024);
const y = Phaser.Math.Between(0, 768);
this.add.image(x, y, 'game', frames[i]);
}
- Phaser.Math.Between генерирует случайное целое число в заданном диапазоне для позиций X и Y.
- this.add.image создает игровой объект Image. Четвертый аргумент frames[i] указывает, какой именно кадр из атласа 'game' использовать для этого изображения. Phaser автоматически найдет координаты этого фрейма в одном из загруженных файлов изображений.
Конфигурация игры и запуск сцены
Весь код должен быть запущен в контексте игры Phaser. Конфигурационный объект config определяет основные параметры.
const config = {
type: Phaser.AUTO,
width: 1024,
height: 768,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
- type: Phaser.AUTO позволяет Phaser самому выбрать рендерер (WebGL или Canvas).
- width / height: Размер игрового холста.
- parent: ID HTML-элемента, в который будет встроен canvas игры. Если элемента с таким ID нет, canvas будет добавлен в тело документа.
- scene: Класс сцены, которая будет запущена сразу после инициализации игры. В нашем случае это Example, где определены методы preload и create.
Создание экземпляра new Phaser.Game(config) запускает весь процесс.
Что попробовать дальше
Использование мультиатласов в Phaser — это мощный прием для оптимизации загрузки графики в ваших играх. Вы научились загружать такой атлас с помощью load.multiatlas, получать доступ ко всем его фреймам и создавать из них игровые объекты. Для экспериментов попробуйте: создать свой мультиатлас с помощью инструментов вроде TexturePacker или Shoebox; динамически добавлять и удалять отдельные текстуры из мультиатласа в runtime; использовать мультиатласы для анимаций спрайтов, подключая this.anims.create. Это откроет новые возможности для структурирования ресурсов в больших проектах.
