Создание анимации из разных текстур

Анимация в Phaser строится на последовательной смене кадров. В роли кадров могут выступать:

  • отдельные изображения (разные текстуры),
  • кадры спрайт-листа,
  • кадры текстурного атласа.

Создание анимации из разных текстур особенно актуально, когда графика хранится в виде отдельных файлов: run1.png, run2.png, run3.png и т.д. Такой подход часто используется на ранних этапах разработки или при ручной подготовке графики без упаковки в атлас.

Phaser позволяет объединить такие текстуры в единую анимацию через менеджер анимаций this.anims.


Загрузка отдельных текстур

Перед созданием анимации необходимо загрузить каждую текстуру в сцене. Загрузка выполняется в методе preload().

preload() {
    this.load.image('run1', 'assets/run1.png');
    this.load.image('run2', 'assets/run2.png');
    this.load.image('run3', 'assets/run3.png');
    this.load.image('run4', 'assets/run4.png');
}

Каждой текстуре присваивается уникальный ключ. Именно эти ключи используются при формировании кадров анимации.


Создание анимации из отдельных текстур

Анимация создаётся в методе create() с помощью this.anims.create().

create() {
    this.anims.create({
        key: 'run',
        frames: [
            { key: 'run1' },
            { key: 'run2' },
            { key: 'run3' },
            { key: 'run4' }
        ],
        frameRate: 10,
        repeat: -1
    });
}

Основные параметры:

  • key — уникальное имя анимации.

  • frames — массив кадров.

  • frameRate — количество кадров в секунду.

  • repeat:

    • -1 — бесконечное повторение,
    • 0 — проигрывание один раз,
    • n — повтор n раз.

Каждый кадр задаётся объектом { key: 'имя_текстуры' }.


Создание спрайта и запуск анимации

После объявления анимации создаётся игровой объект, чаще всего спрайт:

create() {
    this.player = this.add.sprite(400, 300, 'run1');
    this.player.play('run');
}

В конструкторе спрайта указывается первая текстура, которая будет отображаться до запуска анимации. Метод play() запускает анимацию по её ключу.


Использование разных текстур одного размера

Все текстуры в анимации должны:

  • иметь одинаковые размеры,
  • совпадать по точке привязки (origin),
  • соответствовать одинаковому масштабу.

Если размеры различаются, объект будет визуально «прыгать» при смене кадров.

Выравнивание можно задать через:

this.player.setOrigin(0.5, 0.5);

Управление скоростью анимации

Скорость регулируется двумя способами:

Через frameRate

frameRate: 12

Через duration

Вместо frameRate можно указать общую длительность в миллисекундах:

this.anims.create({
    key: 'run',
    frames: [...],
    duration: 800,
    repeat: -1
});

Phaser автоматически рассчитает частоту смены кадров.


Управление воспроизведением

Остановка анимации

this.player.stop();

Пауза

this.player.anims.pause();

Возобновление

this.player.anims.resume();

Проверка состояния

if (this.player.anims.isPlaying) {
    // анимация воспроизводится
}

Динамическое создание кадров

Если текстуры имеют систематические имена (run1, run2, run3…), массив кадров можно сформировать программно:

create() {
    const frames = [];

    for (let i = 1; i <= 4; i++) {
        frames.push({ key: 'run' + i });
    }

    this.anims.create({
        key: 'run',
        frames: frames,
        frameRate: 10,
        repeat: -1
    });
}

Подход удобен при большом количестве кадров.


Локальные и глобальные анимации

Менеджер анимаций в Phaser глобальный для всей игры. Если анимация создаётся в одной сцене, она доступна в других сценах.

Проверка существования анимации:

if (!this.anims.exists('run')) {
    this.anims.create({...});
}

Это предотвращает ошибку повторного создания.


Использование события завершения анимации

Для однократных анимаций часто требуется выполнить действие после завершения.

this.player.on('animationcomplete', (animation) => {
    if (animation.key === 'run') {
        console.log('Анимация завершена');
    }
});

Можно также подписаться на конкретную анимацию:

this.player.on('animationcomplete-run', () => {
    console.log('Run завершена');
});

Анимация с разными наборами текстур

Возможна ситуация, когда анимация должна использовать текстуры из разных логических групп:

this.anims.create({
    key: 'combo',
    frames: [
        { key: 'attack1' },
        { key: 'attack2' },
        { key: 'effect1' },
        { key: 'effect2' }
    ],
    frameRate: 15,
    repeat: 0
});

Phaser не ограничивает использование кадров одной текстурой — можно комбинировать любые заранее загруженные изображения.


Производительность и оптимизация

Создание анимации из отдельных текстур удобно, но имеет ограничения:

  1. Увеличивается количество HTTP-запросов при загрузке.
  2. Больше переключений текстур на GPU, что снижает производительность.
  3. Отсутствует batching, если текстуры разные.

В производственных проектах рекомендуется использовать:

  • спрайт-листы,
  • текстурные атласы.

Тем не менее, для прототипов и небольших игр анимация из отдельных изображений полностью оправдана.


Управление задержкой между кадрами

Для тонкой настройки можно задать индивидуальную длительность кадра:

this.anims.create({
    key: 'run',
    frames: [
        { key: 'run1', duration: 100 },
        { key: 'run2', duration: 200 },
        { key: 'run3', duration: 100 },
        { key: 'run4', duration: 150 }
    ],
    repeat: -1
});

Это позволяет создавать нестандартный ритм движения.


Использование анимации в разных состояниях персонажа

Часто персонаж имеет несколько анимаций:

this.anims.create({ key: 'idle', frames: [...] });
this.anims.create({ key: 'run', frames: [...] });
this.anims.create({ key: 'jump', frames: [...] });

Переключение выполняется в методе update():

if (cursors.left.isDown) {
    this.player.play('run', true);
} else {
    this.player.play('idle', true);
}

Второй параметр true предотвращает перезапуск анимации, если она уже воспроизводится.


Ошибки при создании анимации из текстур

Наиболее распространённые проблемы:

  1. Неправильный ключ текстуры.
  2. Попытка создать анимацию до загрузки ресурсов.
  3. Повторное создание анимации с тем же ключом.
  4. Разные размеры кадров.
  5. Запуск анимации у объекта, не поддерживающего компонент Animation.

Phaser выводит предупреждения в консоль, что облегчает диагностику.


Расширенные возможности

Обратное воспроизведение

this.player.playReverse('run');

Запуск с определённого кадра

this.player.anims.play('run', true, 2);

Изменение скорости во время выполнения

this.player.anims.timeScale = 2;

Значение 1 — нормальная скорость, 2 — в два раза быстрее, 0.5 — в два раза медленнее.


Создание анимации из разных текстур в Phaser представляет собой гибкий механизм управления последовательной сменой изображений. Несмотря на простоту реализации, он предоставляет полный контроль над кадрами, их длительностью, скоростью и логикой воспроизведения, что делает его эффективным инструментом при разработке 2D-игр различной сложности.