О чем этот пример
Плавные движения — основа визуального восприятия игры. Phaser предлагает мощную систему твинов, которая позволяет анимировать свойства объектов с различными эффектами плавности (easing). В этой статье мы разберем, как использовать один из самых выразительных и 'игровых' типов easing — Bounce. Он имитирует отскок мяча, придавая анимации ощущение веса, упругости и физической достоверности, что идеально подходит для персонажей, предметов или UI-элементов, которые должны привлекать внимание. Вы научитесь применять три его вариации (`in`, `out`, `inOut`) на практическом примере летающих тарелок.
Версия 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, 'Bounce Ease').setFontSize(32).setShadow(2, 2);
this.add.text(750, 70, 'Bounce.in').setShadow(2, 2).setOrigin(1, 0);
this.add.text(750, 255, 'Bounce.out').setShadow(2, 2).setOrigin(1, 0);
this.add.text(750, 440, 'Bounce.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: 'bounce.in'
});
this.tweens.add({
targets: ufo2,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'bounce.out'
});
this.tweens.add({
targets: ufo3,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'bounce.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 мы загружаем фоновое изображение и три спрайта для наших анимированных объектов. Обратите внимание, что базовый URL для загрузки уже задан, что удобно для примеров.
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 мы сначала размещаем фон и текстовые метки, которые объясняют, какой тип Bounce будет использоваться для каждого объекта. Для позиционирования текста справа используется метод .setOrigin(1, 0), который выравнивает текст по правому краю.
create ()
{
this.add.image(400, 300, 'bg');
this.add.text(20, 20, 'Bounce Ease').setFontSize(32).setShadow(2, 2);
this.add.text(750, 70, 'Bounce.in').setShadow(2, 2).setOrigin(1, 0);
this.add.text(750, 255, 'Bounce.out').setShadow(2, 2).setOrigin(1, 0);
this.add.text(750, 440, 'Bounce.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');
// ... твины будут созданы далее
}
Создание твина с эффектом Bounce.in
Первый твин применяется к объекту ufo1 с параметром ease: 'bounce.in'. Этот тип easing создает эффект, при котором объект начинает движение с серии небольших отскоков, как будто он падает на землю, а затем переходит в плавное движение. Анимация начинается с 'упругого' старта.
Ключевые параметры конфигурации:
* targets: объект или массив объектов для анимации.
* `x`: 700 — конечная координата по оси X.
* duration: 2000 — длительность одного цикла анимации в миллисекундах.
* repeat: -1 — бесконечное повторение.
* hold: 500 — пауза в конце каждого цикла, перед началом повторения.
* repeatDelay: 500 — дополнительная пауза перед повторением.
this.tweens.add({
targets: ufo1,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'bounce.in'
});
Создание твина с эффектом Bounce.out
Второй твин использует ease: 'bounce.out'. Это противоположность первому варианту. Объект ufo2 движется плавно, а завершает свою анимацию серией отскоков, словно приземляясь на поверхность. Этот эффект отлично подходит для завершающих действий, например, когда предмет падает на пол.
this.tweens.add({
targets: ufo2,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'bounce.out'
});
Создание твина с эффектом Bounce.inOut
Третий твин, с ease: 'bounce.inout', комбинирует оба предыдущих эффекта. Объект ufo3 начинает движение с отскоков и заканчивает отскоками, создавая полный цикл 'упругого' движения. Обратите внимание на написание в нижнем регистре: 'bounce.inout'. Эта вариация наиболее полно имитирует поведение прыгающего мяча.
this.tweens.add({
targets: ufo3,
x: 700,
duration: 2000,
repeat: -1,
hold: 500,
repeatDelay: 500,
ease: 'bounce.inout'
});
Настройка игры и запуск
Финальный шаг — конфигурация и инстанцирование объекта игры Phaser.Game. В конфиге указаны основные параметры: тип рендерера, размеры холста, цвет фона, родительский HTML-элемент и наша сцена Example.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Easing-функция Bounce — это простой, но мощный инструмент для добавления физической убедительности и игривости в анимацию вашего проекта. Поэкспериментируйте, применяя эти твины не только к позиции (`x,y), но и к масштабу (scale), вращению (angle) или прозрачности (alpha) объектов. Попробуйте комбинировать разные easing-функции для разных свойств одного объекта или создайте цепочку твинов с помощьюtweens.chain()`, чтобы строить более сложные анимационные последовательности.
