О чем этот пример
Анимации в играх часто требуют не только плавного движения, но и пауз между действиями. Например, враг атакует, затем замирает на секунду перед следующей атакой. Встроенный механизм Phaser Tweens позволяет легко создавать такие последовательности с помощью параметра `completeDelay`. В этой статье разберем, как использовать эту опцию для создания циклических анимаций с паузами, что особенно полезно для патрулирования врагов, мигающих интерфейсов или любых повторяющихся действий.
Версия 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.image('block', 'assets/sprites/block.png');
}
create ()
{
this.marker = this.add.image(100, 300, 'block').setAlpha(0.3);
this.image = this.add.image(100, 300, 'block');
this.moveBlock();
}
resetBlock()
{
this.tweens.add({
targets: this.image,
x: 100,
duration: 1000,
ease: 'Power2',
completeDelay: 2000,
onComplete: function () {
this.moveBlock();
}.bind(this),
});
}
moveBlock()
{
this.tweens.add({
targets: this.image,
x: 700,
duration: 1000,
ease: 'Power2',
completeDelay: 2000,
onComplete: function () {
this.resetBlock();
}.bind(this),
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
var game = new Phaser.Game(config);
Что делает параметр `completeDelay`?
Параметр completeDelay в конфигурации твина задает задержку в миллисекундах **перед** вызовом функции обратного вызова onComplete. Это ключевой момент: задержка происходит уже после того, как основная анимация (например, перемещение спрайта из точки А в точку Б) завершена, но до того, как выполнится код в onComplete.
Это позволяет создавать четкие последовательности: действие -> пауза -> следующее действие. Без этого параметра пришлось бы вручную создавать таймеры или вкладывать твины, что усложнило бы код.
Разбор примера: бесконечное движение блока
В предоставленном примере создается сцена с двумя спрайтами: основной (this.image) и полупрозрачный маркер (this.marker), показывающий начальную позицию.
Цикл анимации запускается в методе create() вызовом this.moveBlock().
create ()
{
this.marker = this.add.image(100, 300, 'block').setAlpha(0.3);
this.image = this.add.image(100, 300, 'block');
this.moveBlock();
}
Основная логика заложена в двух методах: moveBlock() и resetBlock(). Они вызывают друг друга через onComplete, создавая бесконечный цикл 'туда-сюда'.
Анализ метода `moveBlock`
Метод moveBlock запускает твин, который перемещает блок от координаты x=100 к x=700.
this.tweens.add({
targets: this.image, // Цель анимации
x: 700, // Конечная координата X
duration: 1000, // Длительность движения (1 секунда)
ease: 'Power2', // Функция плавности
completeDelay: 2000, // Ключевой параметр: пауза в 2 секунды ПОСЛЕ движения
onComplete: function () {
this.resetBlock(); // После паузы вызываем метод сброса
}.bind(this),
});
Последовательность:
1. Блок движется вправо за 1 секунду.
2. Блок **останавливается** на 2 секунды (благодаря completeDelay: 2000).
3. Срабатывает onComplete и вызывает resetBlock().
Анализ метода `resetBlock`
Метод resetBlock зеркально противоположен. Он возвращает блок на стартовую позицию.
this.tweens.add({
targets: this.image,
x: 100, // Возвращаем блок обратно, к маркеру
duration: 1000,
ease: 'Power2',
completeDelay: 2000, // Снова пауза в 2 секунды после возвращения
onComplete: function () {
this.moveBlock(); // После паузы снова запускаем движение вправо
}.bind(this),
});
Таким образом, цикл становится бесконечным: движение вправо (1с) -> пауза (2с) -> движение влево (1с) -> пауза (2с) -> и так далее. Обратите внимание на использование .bind(this) в onComplete — это необходимо, чтобы внутри функции-колбэка this указывал на экземпляр сцены, а не на сам твин.
Практическое применение и вариации
Параметр completeDelay универсален. Вот несколько идей, как его можно применить:
* **Патрулирование врага:** Задайте несколько ключевых точек. После достижения каждой точки добавляйте completeDelay, чтобы враг 'осматривался'.
* **Мигание элемента интерфейса:** Твин на изменение alpha с completeDelay создаст эффект мигания с паузами.
* **Задержка перед исчезновением:** После получения урона спрайт может покраснеть (твин цвета), подождать (completeDelay) и только потом исчезнуть или вернуться в нормальное состояние.
Важно: completeDelay — это задержка **после** анимации. Если вам нужна задержка **перед** началом анимации, используйте параметр delay.
// Задержка ПЕРЕД началом движения
this.tweens.add({
targets: this.image,
x: 700,
duration: 1000,
delay: 2000, // Ждем 2 секунды, потом начинаем движение
onComplete: function() { /* ... */ }
});
Что попробовать дальше
Параметр completeDelay в системе твинов Phaser — это простой, но мощный инструмент для управления временем в анимациях. Он избавляет от необходимости управлять отдельными таймерами и позволяет создавать сложные последовательности действий прямо внутри конфигурации твина. Для экспериментов попробуйте изменить completeDelay и delay в примере, чтобы увидеть разницу, или создайте цепочку из нескольких твинов с паузами для одного объекта.
