О чем этот пример
Использование текстурных атласов — ключевая техника оптимизации для 2D-игр. Вместо загрузки десятков отдельных файлов изображений вы упаковываете все спрайты в один большой файл и загружаете его вместе с JSON-файлом, описывающим координаты каждого элемента. Это значительно сокращает количество HTTP-запросов, ускоряет загрузку игры и упрощает управление ассетами. В этой статье мы разберем, как загрузить атлас и отображать из него конкретные кадры (frames) на сцене, используя пример из официальной документации 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.atlas('atlas', 'assets/atlas/megaset-1.png', 'assets/atlas/megaset-1.json');
}
create ()
{
this.add.image(400, 200, 'atlas', 'titan-mech');
this.add.image(400, 400, 'atlas', 'ship');
this.add.image(400, 600, 'atlas', 'supercars-parsec');
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка ассетов и загрузка атласа
Перед началом работы нужны два файла: изображение-атлас (например, PNG) и JSON-файл с данными о координатах и размерах каждого спрайта внутри этого изображения. Эти файлы можно сгенерировать с помощью таких инструментов, как TexturePacker или Shoebox.
В методе preload() сцены мы используем this.load.atlas() для загрузки обоих файлов. Первый аргумент — это уникальный ключ атласа, по которому мы будем к нему обращаться. Второй и третий аргументы — пути к файлам изображения и данных соответственно.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.atlas('atlas', 'assets/atlas/megaset-1.png', 'assets/atlas/megaset-1.json');
}
Здесь также используется this.load.setBaseURL() для задания базового URL, что позволяет указывать относительные пути для ассетов. После выполнения этого метода Phaser загрузит атлас и распарсит JSON, создав внутреннюю карту всех кадров.
Отображение кадров из атласа на сцене
После загрузки атласа в методе create() мы можем создавать изображения, используя конкретные кадры из него. Для этого используется перегруженный метод this.add.image(x, y, textureKey, frameKey).
- `xиy` — координаты центра изображения на экране.
- textureKey — ключ атласа, который мы указали при загрузке (в нашем случае 'atlas').
- frameKey — строковый ключ конкретного спрайта внутри атласа. Этот ключ должен соответствовать имени, указанному в JSON-файле атласа.
create ()
{
this.add.image(400, 200, 'atlas', 'titan-mech');
this.add.image(400, 400, 'atlas', 'ship');
this.add.image(400, 600, 'atlas', 'supercars-parsec');
}
В примере мы размещаем три разных спрайта ('titan-mech', 'ship', 'supercars-parsec') из одного атласа в разных позициях по вертикали. Phaser автоматически находит границы каждого кадра в атласе и отрисовывает только нужную часть изображения.
Конфигурация игры и запуск сцены
Как и в любом проекте на Phaser, нам нужна базовая конфигурация игры. В объекте config мы указываем тип рендерера, элемент-контейнер на странице и стартовую сцену. Затем создаем экземпляр игры new Phaser.Game(config), который автоматически запускает жизненный цикл сцены (preload, create, update).
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Ключ type: Phaser.AUTO позволяет Phaser самому выбрать оптимальный рендерер (WebGL или Canvas). parent — это id HTML-элемента, в который будет встроен canvas игры. Класс Example, который мы определили ранее, передается как стартовая сцена.
Практические советы и отладка
1. **Проверка ключей кадров**: Если спрайт не появляется на сцене, первым делом убедитесь, что ключ кадра (frameKey) точно совпадает с именем в JSON-файле атласа. Регистр символов имеет значение.
2. **Использование загрузчика**: Метод this.load.atlas() является частью системы загрузки Phaser. Все ассеты, загруженные в preload(), становятся доступны только после того, как сцена перейдет в состояние create().
3. **Доступ к списку кадров**: После загрузки вы можете получить текстуру и проверить список всех доступных кадров через кэш текстур:
// В методе create() или после него
const texture = this.textures.get('atlas');
const frameNames = texture.getFrameNames();
console.log(frameNames); // Выведет массив всех ключей кадров в атласе
4. **Оптимизация**: Объединяйте в один атлас спрайты, которые используются на одном уровне или в одной механике игры, чтобы минимизировать переключения текстур (texture swaps) во время рендеринга.
Что попробовать дальше
Работа с текстурными атласами в Phaser проста и эффективна. Всего два метода — load.atlas() для загрузки и add.image() с указанием ключа кадра — позволяют организовать ваши графические ресурсы и повысить производительность игры. Для экспериментов попробуйте:
- Анимировать спрайты, используя кадры из атласа с помощью this.anims.create().
- Создать несколько атласов для разных уровней игры и динамически их подгружать.
- Реализовать систему подсказок, которая выводит в консоль все доступные ключи кадров из загруженного атласа.
