О чем этот пример
Визуальные эффекты — мощный инструмент для оживления игровых объектов. В этом примере мы используем встроенный в Phaser 3 фильтр `barrel` для создания динамической деформации спрайтов, имитирующей эффект сжатия и отскока. Такой подход позволяет добавить интерактивности и отзывчивости элементам интерфейса или игровым персонажам без необходимости создавать сложные анимации вручную. Мы разберем, как подключить фильтр, управлять его параметрами через твины и реагировать на действия игрока.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Block extends Phaser.GameObjects.Sprite
{
constructor (scene, x, y)
{
super(scene, x, y, 'block');
this.setScale(0.9);
this.enableFilters();
// Enlarge filter view.
this.focusFiltersOverride(undefined, undefined, this.width + 64, this.height + 64);
this.barrel = this.filters.internal.addBarrel(0.75);
this.amount = 1;
this.allowClick = true;
this.setInteractive();
this.on('pointerdown', () => this.clicked());
this.startTween(this.amount);
}
startTween (amount)
{
this.barrel.amount = 0.75;
this.pulseTween = this.scene.tweens.add({
targets: this.barrel,
amount,
yoyo: true,
duration: 600 - (amount * 100),
loop: -1,
ease: 'sine.inout'
});
}
clicked ()
{
if (this.amount < 2 && this.allowClick)
{
this.pulseTween.stop();
this.allowClick = false;
this.scene.tweens.add({
targets: this.barrel,
amount: 0.3,
duration: 100,
yoyo: true,
ease: 'sine.out',
onComplete: () => this.tweenStop()
});
}
}
tweenStop ()
{
this.amount += 0.25;
this.startTween(this.amount);
this.allowClick = true;
}
}
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('block', 'assets/sprites/block-slime.png');
}
create ()
{
for (let y = 0; y < 2; y++)
{
for (let x = 0; x < 3; x++)
{
this.add.existing(new Block(this, 144 + x * 256, 180 + y * 256));
}
}
this.add.text(10, 16, 'Click the Blocks');
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#47255b',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка и настройка фильтра
Класс Block наследуется от Phaser.GameObjects.Sprite и отвечает за интерактивный спрайт. Ключевой этап — активация и конфигурация фильтров для этого объекта.
this.enableFilters();
this.focusFiltersOverride(undefined, undefined, this.width + 64, this.height + 64);
this.barrel = this.filters.internal.addBarrel(0.75);
Метод enableFilters() включает систему фильтров для спрайта. focusFiltersOverride() расширяет область рендеринга фильтра, чтобы деформация не обрезалась краями спрайта. this.filters.internal.addBarrel(0.75) создает фильтр типа barrel с начальным значением параметра amount, равным 0.75. Этот параметр управляет силой деформации: чем больше значение, тем сильнее эффект.
Анимация эффекта с помощью твинов
Для создания плавной пульсации используется система твинов Phaser. Метод startTween запускает бесконечную анимацию, которая циклически меняет параметр amount фильтра.
this.pulseTween = this.scene.tweens.add({
targets: this.barrel,
amount,
yoyo: true,
duration: 600 - (amount * 100),
loop: -1,
ease: 'sine.inout'
});
Твин применяется к объекту this.barrel (нашему фильтру) и анимирует его свойство amount. Флаги yoyo: true и loop: -1 заставляют анимацию колебаться между начальным и целевым значением бесконечно. ease: 'sine.inout' задает плавное ускорение и замедление. Длительность анимации duration динамически уменьшается с ростом amount, что ускоряет пульсацию.
Обработка клика и изменение состояния
При клике на спрайт текущая анимация пульсации останавливается и запускается быстрый твин, имитирующий резкое сжатие объекта.
clicked() {
if (this.amount < 2 && this.allowClick) {
this.pulseTween.stop();
this.allowClick = false;
this.scene.tweens.add({
targets: this.barrel,
amount: 0.3,
duration: 100,
yoyo: true,
ease: 'sine.out',
onComplete: () => this.tweenStop()
});
}
}
this.pulseTween.stop() прерывает циклическую пульсацию. Новый твин резко меняет amount до 0.3 (сильное сжатие) и обратно за 100 мс. Флаг allowClick блокирует повторные клики во время анимации. После завершения твина (onComplete) вызывается tweenStop(), где увеличивается базовое значение amount и перезапускается пульсация с новой скоростью.
Создание сцены и размещение объектов
В сцене Example загружается текстура и в цикле создаются несколько экземпляров Block, которые располагаются сеткой.
create() {
for (let y = 0; y < 2; y++) {
for (let x = 0; x < 3; x++) {
this.add.existing(new Block(this, 144 + x * 256, 180 + y * 256));
}
}
this.add.text(10, 16, 'Click the Blocks');
}
this.add.existing() добавляет созданный объект Block в систему отображения сцены. Каждый блок получает уникальные координаты, рассчитанные на основе индексов `xиy. Текстовое поле с инструкцией создается с помощьюthis.add.text()`.
Что попробовать дальше
Фильтр barrel — это простой, но эффективный способ добавить динамическую деформацию спрайтам. Комбинируя его с системой твинов Phaser, можно создавать отзывчивые эффекты для кнопок, врагов или элементов окружения. Для экспериментов попробуйте изменить начальное значение amount, использовать другие easing-функции для твинов или применить фильтр к группе объектов одновременно. Также можно исследовать другие встроенные фильтры, такие как glow или displacement, для создания более сложных визуальных композиций.
