О чем этот пример
Анимация движения объектов — основа игровой динамики. Часто нужно, чтобы траектория или цель анимации менялась в процессе, реагируя на игровые события. Phaser Tweens позволяет задавать не только статичные значения, но и вычислять их динамически с помощью функций `getStart` и `getEnd`. Эта техника открывает путь к созданию сложных, "живых" движений, таких как постепенное смещение цели или пружинящие эффекты, без ручного управления кадрами. В статье разберем пример, где шар движется по сложной траектории, меняя точку отскока на каждом цикле.
Версия 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('ball', 'assets/sprites/shinyball.png');
}
create ()
{
var image = this.add.image(100, 100, 'ball');
var destX = 700;
// TODO: Cache the start and end values so that on a Tween LOOP (not a TweenData repeat) it can reset them :)
var tween = this.tweens.add({
targets: image,
props: {
y: {
value: 500,
duration: 8000,
ease: 'Power1'
},
x: {
duration: 400,
yoyo: true,
repeat: 8,
ease: 'Sine.easeInOut',
value: {
getEnd: function (target, key, value)
{
destX -= 30;
return destX;
},
getStart: function (target, key, value)
{
return value + 30;
}
}
}
}
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Сцена и базовая загрузка
Код начинается с создания стандартной сцены Phaser 3. В методе preload загружается одно изображение — спрайт шара. Обратите внимание, что используется setBaseURL для указания базового пути к ресурсам. Это удобно, если ваши ассеты лежат в определенной структуре каталогов.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('ball', 'assets/sprites/shinyball.png');
}
Создание объекта и определение Tween
В методе create мы создаем экземпляр изображения шара и определяем переменную destX, которая будет хранить конечную координату X для анимации. Это наша внешняя переменная для управления логикой.
var image = this.add.image(100, 100, 'ball');
var destX = 700;
Далее создается объект твина с помощью this.tweens.add. Ключевой параметр targets указывает, к какому объекту применяется анимация. Внутри props мы определяем свойства, которые будут анимированы: `yиx`.
var tween = this.tweens.add({
targets: image,
props: {
// ... свойства y и x будут здесь
}
});
Простая анимация по оси Y
Свойство `yанимируется классическим способом: задается конечное значениеvalue, длительностьdurationи функция плавностиease. Шар будет двигаться вниз до Y=500 за 8 секунд с линейным ускорением (Power1`).
y: {
value: 500,
duration: 8000,
ease: 'Power1'
}
Динамическая анимация по оси X
Вот где начинается магия. Для свойства `xмы задаем более сложную конфигурацию. Анимация будет короткой (400 мс), с отскоком (yoyo: true) и повторится 8 раз (repeat: 8). Функция плавностиSine.easeInOut` создает мягкий старт и остановку.
x: {
duration: 400,
yoyo: true,
repeat: 8,
ease: 'Sine.easeInOut',
// ... динамическое значение value
}
Вместо статичного числа параметр value является объектом с двумя функциями: getEnd и getStart. Эти функции вызываются твином для вычисления значений в реальном времени.
Функция getEnd определяет конечную точку каждого цикла анимации. Каждый раз, когда она вызывается, она уменьшает глобальную переменную destX на 30 и возвращает новое значение. Таким образом, с каждым циклом цель движения по X смещается влево.
value: {
getEnd: function (target, key, value)
{
destX -= 30;
return destX;
},
getStart: function (target, key, value)
{
return value + 30;
}
}
Функция getStart определяет начальную точку. Она берет текущее значение свойства (value) и добавляет к нему 30. Это создает эффект "шага": после каждого отскока шар начинает движение не с той же точки, а чуть правее, компенсируя смещение конечной цели. В итоге шар совершает серию горизонтальных колебаний, постепенно смещаясь влево, одновременно плавно опускаясь вниз.
Конфигурация и запуск игры
За пределами класса сцены определяется стандартный объект конфигурации игры config, в котором указывается тип рендерера, размеры холста, цвет фона, родительский элемент и основная сцена.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
Игра инициализируется созданием нового экземпляра Phaser.Game с этой конфигурацией.
const game = new Phaser.Game(config);
Что попробовать дальше
Динамические свойства getStart и getEnd в Phaser Tweens — мощный инструмент для создания нелинейных, адаптивных анимаций. Они позволяют анимации реагировать на состояние игры или предыдущие циклы. Для экспериментов попробуйте
- Изменить логику в
getEnd, чтобы цель смещалась по синусоиде или случайным образом - Привязать значение
destXк положению курсора мыши, чтобы шар "преследовал" его рывками - Использовать
getActiveдля модификации анимации прямо во время её выполнения, создавая эффекты инерции или сопротивления
