О чем этот пример
Стандартные твины в Phaser предсказуемы и синхронны, что не всегда соответствует хаотичному игровому миру. Функция `delay` в конфигурации твина позволяет задать не фиксированную паузу, а динамически рассчитанную задержку для каждого запуска. Это открывает двери к созданию более живых, "неровных" и интересных анимаций, например, для появления врагов волнами, хаотичного мерцания объектов или случайного времени реакции. В этой статье разберем пример, где задержка твина рассчитывается случайным образом при каждом запуске, и объясним, как это работает изнутри.
Версия 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('bg', 'assets/skies/sunset.png');
this.load.image('ball', 'assets/sprites/ball-pink.png');
}
create ()
{
this.add.image(400, 300, 'bg');
this.add.text(10, 10, 'This Tween has a random delay value. Click to start it.', { font: '16px Courier', fill: '#ffffff' });
const text = this.add.text(10, 40, '', { font: '16px Courier', fill: '#ffffff' });
const ball = this.add.image(100, 300, 'ball').setScale(0.5);
const tween = this.tweens.add({
targets: ball,
x: 700,
yoyo: true,
duration: 1000,
persist: true,
paused: true,
ease: 'bounce.out',
delay: function (target, key, value, index, total)
{
const delay = Math.random() * 2000;
text.setText(`Tween Delay: ${delay}`);
return delay;
}
});
this.input.on('pointerdown', function () {
if (!tween.isPlaying())
{
tween.play();
}
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены: загрузка и создание объектов
Как и всегда, работа начинается с методов жизненного цикла сцены Phaser. В preload мы загружаем два изображения: фон и спрайт мяча. В методе create мы создаем визуальные элементы, с которыми будем работать.
this.add.image(400, 300, 'bg');
const text = this.add.text(10, 40, '', { font: '16px Courier', fill: '#ffffff' });
const ball = this.add.image(100, 300, 'ball').setScale(0.5);
Первой мы размещаем фоновое изображение. Затем создаем текстовый объект text для вывода информации о задержке. Его начальное значение — пустая строка. Объект ball — это наш мяч, который мы будем анимировать. Мы сразу уменьшаем его масштаб вполовину с помощью метода .setScale(0.5) и размещаем у левого края.
Создание твина с функцией задержки
Сердце примера — создание твина с помощью this.tweens.add(). Ключевой параметр здесь — delay. Вместо статичного числа мы передаем функцию.
const tween = this.tweens.add({
targets: ball,
x: 700,
yoyo: true,
duration: 1000,
persist: true,
paused: true,
ease: 'bounce.out',
delay: function (target, key, value, index, total) {
const delay = Math.random() * 2000;
text.setText(`Tween Delay: ${delay}`);
return delay;
}
});
Разберем важные параметры:
* targets: ball: Анимация применяется к объекту ball.
* x: 700: Конечная координата X для движения.
* yoyo: true: После завершения движения мяч вернется в исходную точку.
* duration: 1000: Длительность одного цикла движения (туда или обратно) — 1 секунда.
* persist: true: Твин не будет автоматически уничтожен после завершения, что позволяет перезапускать его.
* paused: true: Твин создается в приостановленном состоянии и не начнется сам.
* ease: 'bounce.out': Функция плавности, создающая эффект отскока в конце движения.
Функция delay вызывается системой твинов в момент старта анимации. Она генерирует случайное число от 0 до 2000 миллисекунд, выводит его в интерфейс и возвращает как значение задержки. Именно столько времени твин будет ждать перед началом движения.
Запуск твина по клику
Поскольку твин создан с параметром paused: true, нам нужен способ его запустить. Мы навешиваем обработчик события клика (или касания) на всю сцену.
this.input.on('pointerdown', function () {
if (!tween.isPlaying()) {
tween.play();
}
});
Обработчик проверяет, не воспроизводится ли твин уже сейчас, с помощью метода tween.isPlaying(). Если твин простаивает, мы вызываем tween.play(). При каждом клике функция delay выполнится заново, рассчитав новое случайное значение, и мяч начнет движение после новой, непредсказуемой паузы.
Сборка и запуск игры
Финальный шаг — конфигурация и инстанцирование игры Phaser. Эта часть кода стандартна и определяет базовые настройки приложения.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Конфиг задает автоматический выбор рендерера (Phaser.AUTO), размеры холста, цвет фона (используется, пока не загрузились ресурсы), ID HTML-элемента для встраивания и нашу сцену Example как стартовую. Создание экземпляра new Phaser.Game(config) запускает весь процесс.
Что попробовать дальше
Использование функции для параметра delay превращает статичную задержку в мощный инструмент для генерации процедурного геймплея. Вы можете рассчитывать паузу не только случайно, но и на основе состояния игры: уровня здоровья врага, дистанции до игрока, количества объектов в пуле. Экспериментируйте: попробуйте сделать так, чтобы задержка зависела от index в массиве targets для создания эффекта "волны", или привяжите ее к громкости звука в игре для визуального feedback. Это простое изменение добавляет анимациям живости и неожиданности.
