О чем этот пример

Спрайт-листы (sprite sheets) — это основа оптимизации игровых ресурсов. Вместо сотен отдельных файлов изображений вы используете один, что ускоряет загрузку и снижает потребление памяти. В этой статье мы разберем, как загружать спрайт-лист в 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.spritesheet('diamonds', 'assets/sprites/diamonds32x24x5.png', { frameWidth: 32, frameHeight: 24 });

    }

    create ()
    {

        this.add.image(0, 0, 'diamonds', 0);
        this.add.image(64, 0, 'diamonds', 1);
        this.add.image(128, 0, 'diamonds', 2);
        this.add.image(32, 32, 'diamonds', 3);
        this.add.image(96, 32, 'diamonds', 4);

    }
}

const config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Загрузка спрайт-листа в `preload`

Все ресурсы в Phaser предварительно загружаются в методе preload сцены. Для спрайт-листов используется метод this.load.spritesheet. Вам необходимо указать уникальный ключ ресурса, путь к файлу и размер одного фрейма.

this.load.spritesheet('diamonds', 'assets/sprites/diamonds32x24x5.png', { frameWidth: 32, frameHeight: 24 });
В этом примере:
- `'diamonds'` — ключ, по которому мы будем обращаться к загруженному спрайт-листу.
- `'assets/sprites/diamonds32x24x5.png'` — путь к файлу изображения. Обратите внимание, что сначала мы задали базовый URL с помощью `this.load.setBaseURL`.
- `{ frameWidth: 32, frameHeight: 24 }` — объект конфигурации, где указаны ширина и высота одного фрейма. Phaser автоматически "нарежет" изображение на сетку из фреймов указанного размера. Из названия файла `diamonds32x24x5.png` можно понять, что размер фрейма 32x24, а всего фреймов 5.

Отображение отдельных фреймов в `create`

После загрузки ресурсов управление передается методу create. Чтобы отобразить отдельный фрейм из спрайт-листа, используется метод this.add.image. Ключевое отличие от отображения обычного изображения — передача четвертого аргумента, индекса фрейма.

this.add.image(0, 0, 'diamonds', 0);
this.add.image(64, 0, 'diamonds', 1);
this.add.image(128, 0, 'diamonds', 2);

Здесь: - Первые два аргумента (0, 0) и (64, 0) — это координаты X и Y для размещения изображения на сцене. - Третий аргумент 'diamonds' — ключ загруженного спрайт-листа. - Четвертый аргумент (`0,1,2` и т.д.) — индекс нужного фрейма. Индексация начинается с нуля. Phaser размещает фреймы в спрайт-листе слева направо, сверху вниз.

Понимание структуры спрайт-листа

Визуализация того, как Phaser "видит" ваш спрайт-лист, поможет избежать ошибок. Для файла diamonds32x24x5.png с размером фрейма 32x24 Phaser создаст следующую сетку:

Индексы фреймов в сетке:
[0] [1] [2]
[3] [4]

Именно поэтому в примере фреймы 0, 1, 2 размещены в верхнем ряду (Y=0), а фреймы 3 и 4 — во втором ряду (Y=32, что равно высоте фрейма). Всегда проверяйте, что размер фрейма в конфигурации spritesheet точно соответствует размеру одного элемента в вашем PNG-файле.

Конфигурация игры и сцены

Весь код должен быть запущен в контексте игры Phaser. Для этого создается конфигурационный объект и экземпляр Phaser.Game.

const config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

- type: Phaser.WEBGL — указывает на использование WebGL-рендерера (можно также использовать Phaser.CANVAS). - parent: 'phaser-example' — ID HTML-элемента, в который будет встроен canvas игры. - scene: Example — класс нашей сцены, которая будет запущена сразу при старте игры. Это минимальная конфигурация для запуска примера.

Что попробовать дальше

Работа со спрайт-листами в Phaser проста и эффективна. Вы освоили базовый цикл: загрузка через spritesheet и отображение фреймов через image. Для экспериментов попробуйте

  1. создать анимацию, последовательно меняя индекс фрейма у одного спрайта
  2. загрузить спрайт-лист с другим количеством фреймов и размерами
  3. использовать спрайт-лист для создания кнопок интерфейса с разными состояниями (hover, click)