О чем этот пример
Работа с анимациями — ключевая часть создания динамичных игр. Phaser 3 предоставляет мощную систему твинов, а метод `tweens.chain()` позволяет объединять несколько анимаций в последовательную цепочку. Однако тонкости настройки задержки (`delay`) могут вызвать неожиданное поведение. В этой статье мы разберем конкретный пример, который демонстрирует, как правильно задавать общую задержку для всей цепочки, избегая типичных ошибок. Это знание поможет вам создавать более контролируемые и сложные анимационные последовательности.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
/* global colors, Phaser */
class Example extends Phaser.Scene
{
preload ()
{
this.load.image('mySprite', 'https://labs.phaser.io/assets/particles/red.png');
}
create ()
{
// const sprite = this.add.image(400, 300, 'mySprite');
// this.tweens.chain({
// delay: 1,
// tweens: [
// {
// targets: sprite,
// x: 500
// }
// ]
// });
this.objToTween = this.add.circle(this.scale.width / 2, this.scale.height / 2, 50, 0xff0000);
const chain = this.tweens.chain({
delay: 1,
tweens: [
{ targets: this.objToTween, duration: 500, props: { alpha: 0 } },
{ targets: this.objToTween, duration: 500, props: { alpha: 1 } },
{ targets: this.objToTween, duration: 500, props: { alpha: 0 } },
{ targets: this.objToTween, duration: 500, props: { alpha: 1 } },
],
});
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
new Phaser.Game(config);
Создание объекта для анимации
Прежде чем запускать анимации, нам нужен объект, который будет изменяться. В примере вместо спрайта используется графический примитив — круг. Это удобно для демонстрации, так как не требует внешних ресурсов.
Метод this.add.circle() создает круг с заданными координатами, радиусом и цветом. Центр круга размещается по центру игрового холста, используя свойства this.scale.width и this.scale.height. Ссылка на созданный круг сохраняется в свойстве сцены this.objToTween, чтобы быть доступной для твинов.
this.objToTween = this.add.circle(this.scale.width / 2, this.scale.height / 2, 50, 0xff0000);
Настройка цепочки твинов
Цепочка твинов создается с помощью метода this.tweens.chain(). Он принимает объект конфигурации. Ключевой параметр в нашем примере — delay. Он устанавливает задержку в миллисекундах **перед началом выполнения всей цепочки**. Это важно понимать: задержка применяется один раз к первому твину в последовательности, а не к каждому твину по отдельности.
Массив tweens содержит конфигурации для отдельных анимаций. Каждый элемент массива — это объект, описывающий один твин.
const chain = this.tweens.chain({
delay: 1000, // Задержка 1 секунда (1000 мс) перед стартом цепочки
tweens: [
// Первый твин: плавное исчезновение круга за 500 мс
{ targets: this.objToTween, duration: 500, props: { alpha: 0 } },
// Второй твин: плавное появление круга за 500 мс
{ targets: this.objToTween, duration: 500, props: { alpha: 1 } },
// Третий твин: повторное исчезновение
{ targets: this.objToTween, duration: 500, props: { alpha: 0 } },
// Четвертый твин: повторное появление
{ targets: this.objToTween, duration: 500, props: { alpha: 1 } },
],
});
Обратите внимание: в оригинальном примере значение delay равно `1. Это технически корректно (1 миллисекунда), но на практике такая задержка почти незаметна. В пояснении выше мы использовали значение1000` для наглядности.
Структура отдельного твина в цепочке
Каждый объект в массиве tweens настраивается по тем же правилам, что и обычный твин, создаваемый через this.tweens.add(). Основные свойства:
* targets: объект или массив объектов, к которым применяется анимация.
* duration: длительность анимации в миллисекундах.
* props: объект, ключи которого — это свойства targets, а значения — целевые значения для анимации.
В нашем случае анимируется только свойство alpha (прозрачность) от 1 (полностью видимый) до 0 (полностью прозрачный) и обратно.
{ targets: this.objToTween, duration: 500, props: { alpha: 0 } }
Твины в цепочке выполняются строго последовательно. Второй твин начнется только после полного завершения первого, и так далее.
Распространенная ошибка: задержка для каждого твина
Новички часто предполагают, что параметр delay в конфигурации цепочки добавит паузу между каждым твином. Это не так. delay работает только один раз — в самом начале.
Если вам нужна пауза **между** анимациями в цепочке, ее необходимо явно добавлять в конфигурацию каждого отдельного твина с помощью его собственного свойства delay. Либо можно создать отдельный твин-паузу, который ничего не анимирует.
Пример ошибочного ожидания (так НЕ работает):
// НЕПРАВИЛЬНО: задержка не будет повторяться между твинами.
const chain = this.tweens.chain({
delay: 500, // Сработает только перед первым твином
tweens: [tween1, tween2, tween3]
});
Правильный способ добавить паузы между твинами:
const chain = this.tweens.chain({
tweens: [
{ targets: obj, duration: 500, x: 400 },
// Пауза 300 мс перед следующим твином:
{ targets: obj, duration: 0, delay: 300 },
{ targets: obj, duration: 500, y: 300 },
],
});
Управление и переиспользование цепочки
Метод this.tweens.chain() возвращает объект TweenChain. Его можно сохранить в переменную (как chain в примере) для дальнейшего управления.
С помощью этого объекта вы можете:
* Остановить всю цепочку: chain.stop().
* Перезапустить цепочку с начала: chain.restart().
* Установить флаг повторения для всей цепочки, добавив в изначальную конфигурацию свойство loop (или repeat с repeatDelay).
const chain = this.tweens.chain({
delay: 1000,
tweens: [ /* массив твинов */ ],
loop: 3 // Вся цепочка повторится 3 раза
});
// Где-то в коде по условию:
if (playerHit) {
chain.stop(); // Останавливаем анимацию при попадании
}
Это дает высокий уровень контроля над сложными анимационными последовательностями.
Что попробовать дальше
Использование tweens.chain() в Phaser 3 — это мощный инструмент для создания последовательных анимаций. Главный вывод: общий параметр delay задает задержку только перед стартом всей цепочки, а не между ее элементами. Для создания пауз внутри последовательности используйте свойство delay в конфигурации отдельных твинов.
Для экспериментов попробуйте:
1. Создать цепочку, которая перемещает объект по сложной траектории (например, квадрату), добавляя паузы в каждой вершине.
2. Скомбинировать анимацию разных свойств: alpha, scale, angle.
3. Связать цепочку с игровыми событиями, например, запускать сложную анимацию уничтожения врага при его смерти, а затем останавливать ее, если враг неожиданно воскресает.
