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

Создание плавных и выразительных анимаций — ключ к оживлению ваших игровых персонажей. Часто нужно не просто запустить цикл, а тонко управлять его ритмом: добавить паузу перед началом, вставить задержку между повторами или отобразить статичный кадр в ожидании. Встроенные параметры `delay` и `repeatDelay` в Phaser решают именно эти задачи, избавляя разработчика от ручного управления таймерами. Эта статья на практическом примере с анимацией зомби покажет, как работают эти параметры, чем они отличаются и как их комбинировать для создания более "живых" и управляемых сцен.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.atlas('zombie', 'assets/animations/zombie.png', 'assets/animations/zombie.json');
    }

    create ()
    {
        this.anims.create({
            key: 'walk',
            frames: this.anims.generateFrameNames('zombie', { prefix: 'walk_', end: 8, zeroPad: 3 }),
            repeat: -1,
            frameRate: 8,
            repeatDelay: 1000,
            delay: 3000,
            showBeforeDelay: true
        });

        this.anims.create({ key: 'death', frames: this.anims.generateFrameNames('zombie', { prefix: 'Death_', end: 5, zeroPad: 3 }), frameRate: 12 });

        const rob = this.add.sprite(400, 560, 'zombie').setOrigin(0.5, 1).play('walk');

        this.input.once('pointerdown', function () {
            rob.play('death');
        }, this);
    }
}

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: [ Example ]
};

const game = new Phaser.Game(config);

Разбираем пример: Анимация зомби с задержками

В предоставленном исходном коде создаётся сцена с двумя анимациями для спрайта зомби: циклическая анимация ходьбы (walk) и одноразовая анимация смерти (death). Интерес представляет именно анимация walk, в конфигурации которой используются три ключевых параметра для контроля времени: delay, repeatDelay и showBeforeDelay.

При запуске сцены зомби начинает "идти" не сразу, а после паузы. Давайте подробно изучим, как это работает.

Параметр `delay`: Пауза перед стартом анимации

Параметр delay устанавливает задержку в миллисекундах перед самым первым воспроизведением анимации. Это полезно, когда нужно синхронизировать начало анимации с другими событиями на сцене или создать эффект "задумчивости" персонажа.

В нашем примере анимация walk начнётся только через 3 секунды после вызова метода .play('walk').

this.anims.create({
    key: 'walk',
    // ... другие параметры ...
    delay: 3000, // Задержка 3000 мс (3 секунды) перед первым кадром
    showBeforeDelay: true
});

Параметр `showBeforeDelay`: Что показывать во время ожидания

По умолчанию, во время задержки delay спрайт становится невидимым. Поведение изменяет флаг showBeforeDelay. Если установить его в true, то во время паузы delay на спрайте будет отображаться первый кадр будущей анимации.

В нашем случае зомби в течение 3 секунд будет стоять в позе первого кадра анимации ходьбы, а уже потом начнёт двигаться. Это создаёт более естественный переход от статики к движению.

showBeforeDelay: true // Показывать первый кадр анимации во время задержки `delay`

Параметр `repeatDelay`: Пауза между циклами

Параметр repeatDelay устанавливает задержку в миллисекундах между повторениями анимации. Он работает только для анимаций с repeat: -1 (бесконечный повтор) или repeat: > 0.

После того как анимация walk полностью проиграет свой цикл из 8 кадров, она сделает паузу в 1 секунду, и только затем начнёт следующий цикл. Это позволяет создавать прерывистые, "уставшие" или более реалистичные циклические движения.

repeat: -1,   // Бесконечный повтор
repeatDelay: 1000, // Пауза 1000 мс (1 секунда) между повторами
frameRate: 8  // Скорость 8 кадров в секунду

Смена анимации: Как `delay` влияет на немедленный переход

В примере по клику мыши анимация walk прерывается и запускается death. Важно понимать, что если бы в момент клика ещё шла начальная задержка delay (те самые 3 секунды), она была бы отменена. Параметры delay и showBeforeDelay применяются только к конкретному воспроизведению анимации. При смене анимации через .play() предыдущая останавливается, и все её отложенные события сбрасываются.

this.input.once('pointerdown', function () {
    rob.play('death'); // Немедленная смена анимации, задержки `walk` игнорируются
}, this);

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

Параметры delay, repeatDelay и showBeforeDelay — это мощные инструменты для добавления временно́го контекста в анимации Phaser. Они позволяют легко создавать сложное поведение без написания дополнительного кода для управления таймерами. **Идеи для экспериментов:** 1. Создайте анимацию удара, где delay имитирует замах, а showBeforeDelay показывает боевую стойку. 2. Используйте repeatDelay для анимации мигания UI-элемента (например, подсказки), чтобы оно было не монотонным, а с ритмичными паузами. 3. Скомбинируйте несколько спрайтов с разными значениями delay и repeatDelay для создания несинхронного, "оживлённого" фона (толпа, стая птиц).