О чем этот пример
Плавность анимации часто определяет качество игрового процесса. Phaser предлагает мощную систему твинов, но без правильных функций плавности (easing) движения могут выглядеть механически. В этой статье мы разберем три экспоненциальные функции плавности (`expo.in`, `expo.out`, `expo.inOut`) на практическом примере с летающими тарелками. Вы узнаете, как выбирать нужный ease для создания естественного ускорения и замедления объектов.
Версия 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/tweens/space.png');
this.load.image('ufo1', 'assets/tweens/ufo1.png');
this.load.image('ufo2', 'assets/tweens/ufo2.png');
this.load.image('ufo3', 'assets/tweens/ufo3.png');
}
create ()
{
this.add.image(400, 300, 'bg');
this.add.text(20, 20, 'Exponential Ease').setFontSize(32).setShadow(2, 2);
this.add.text(750, 70, 'Expo.in').setShadow(2, 2).setOrigin(1, 0);
this.add.text(750, 255, 'Expo.out').setShadow(2, 2).setOrigin(1, 0);
this.add.text(750, 440, 'Expo.inOut').setShadow(2, 2).setOrigin(1, 0);
const ufo1 = this.add.image(100, 140, 'ufo1');
const ufo2 = this.add.image(100, 325, 'ufo2');
const ufo3 = this.add.image(100, 510, 'ufo3');
this.tweens.add({
targets: ufo1,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'expo.in'
});
this.tweens.add({
targets: ufo2,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'expo.out'
});
this.tweens.add({
targets: ufo3,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'expo.inout'
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Загрузка ресурсов и основа сцены
Как и в любом проекте Phaser, работа начинается с метода preload. Здесь мы загружаем фоновое изображение и три спрайта летающих тарелок с удаленного сервера, установленного через this.load.setBaseURL.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bg', 'assets/tweens/space.png');
this.load.image('ufo1', 'assets/tweens/ufo1.png');
this.load.image('ufo2', 'assets/tweens/ufo2.png');
this.load.image('ufo3', 'assets/tweens/ufo3.png');
}
В методе create мы размещаем фон, заголовок и текстовые подписи для каждого типа плавности. Важно отметить использование метода .setOrigin(1, 0) для текстовых меток — он выравнивает текст по правому краю (originX = 1) и верхнему краю (originY = 0), что удобно для расположения у правой границы экрана.
this.add.text(750, 70, 'Expo.in').setShadow(2, 2).setOrigin(1, 0);
this.add.text(750, 255, 'Expo.out').setShadow(2, 2).setOrigin(1, 0);
this.add.text(750, 440, 'Expo.inOut').setShadow(2, 2).setOrigin(1, 0);
Создание объектов и настройка твинов
Мы создаем три спрайта тарелок (ufo1, ufo2, ufo3), размещая их вертикально на левой стороне экрана. Каждая тарелка будет двигаться с уникальным типом плавности.
const ufo1 = this.add.image(100, 140, 'ufo1');
const ufo2 = this.add.image(100, 325, 'ufo2');
const ufo3 = this.add.image(100, 510, 'ufo3');
Далее настраиваем анимацию через систему твинов, вызывая this.tweens.add. Ключевой параметр здесь — ease. Он определяет математическую функцию, которая вычисляет промежуточные значения свойства `xмежду начальной (100) и конечной (700) точками за времяduration(2000 мс). Параметрыrepeat: -1,holdиrepeatDelay` заставляют анимацию бесконечно повторяться с паузами, что идеально для демонстрации.
Экспоненциальный вход (Expo.in)
Функция expo.in создает эффект плавного старта с последующим быстрым ускорением. Движение начинается очень медленно, почти незаметно, а затем резко набирает скорость, как ракета при старте. Это достигается за счет экспоненциального роста значения плавности от 0 до 1.
this.tweens.add({
targets: ufo1,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'expo.in'
});
Такой тип хорошо подходит для объектов, которые появляются из состояния покоя: вылет снаряда, начало рывка персонажа.
Экспоненциальный выход (Expo.out)
Функция expo.out — это зеркальная противоположность expo.in. Объект начинает движение быстро, а затем резко замедляется, плавно «притягиваясь» к конечной точке. Это похоже на приземление или точную остановку.
this.tweens.add({
targets: ufo2,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'expo.out'
});
Используйте expo.out для анимаций завершения: заход на посадку, точное размещение предмета в инвентаре, мягкое касание границы экрана.
Экспоненциальный вход-выход (Expo.inOut)
Функция expo.inOut объединяет оба эффекта: плавный старт, быстрый разгон в середине пути и плавное замедление в конце. Это создает наиболее естественное и приятное для глаза движение, имитирующее инерцию реальных объектов.
this.tweens.add({
targets: ufo3,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'expo.inout'
});
Обратите внимание на написание значения: 'expo.inout' (все строчные). Этот тип — универсальный выбор для перемещения персонажей, открытия меню или любых циклических действий, где важны и начало, и конец анимации.
Что попробовать дальше
Экспоненциальные функции плавности в Phaser — это простой способ добавить анимациям физическую достоверность и динамику. Поэкспериментируйте, комбинируя разные ease-функции для нескольких свойств одновременно (например, `xиscale). Попробуйте применитьexpo.inк прозрачности (alpha) для эффекта постепенного появления илиexpo.outк вращению (rotation`) для реалистичной остановки вращающегося элемента. Это мгновенно повысит полировку вашей игры.
