О чем этот пример
Создание визуально привлекательных эффектов — ключ к удержанию внимания игрока. В этом примере мы совместим динамическую геометрию объекта Rope с фильтром свечения GlowFilter, чтобы получить гибкую, переливающуюся светом ленту. Вы научитесь не только применять готовые фильтры, но и анимировать их параметры, а также в реальном времени изменять форму объекта для создания живых, дышащих анимаций. Этот приём отлично подойдёт для фоновых элементов, магических заклинаний или интерфейсных украшений.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
this.rope;
this.count = 0;
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bg', 'assets/rope/background-red.png');
this.load.image('banner', 'assets/rope/fade-one.png');
}
create ()
{
this.add.image(512, 300, 'bg').setAlpha(0.5);
this.rope = this.add.rope(400, 300, 'banner', null, 20);
const fx = this.rope.enableFilters().filters.external.addGlow(0xffffff, 4, 0, 1, false, 10, 32);
this.tweens.add({
targets: fx,
outerStrength: 10,
yoyo: true,
loop: -1,
ease: 'sine.inout'
});
}
update ()
{
this.count += 0.1;
let points = this.rope.points;
for (let i = 0; i < points.length; i++)
{
points[i].y = Math.sin(i * 0.5 + this.count) * 16;
}
this.rope.setDirty();
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и создание Rope
Ключевой объект в этом примере — Rope. Это особый игровой объект (Game Object), представляющий собой растяжимую ленту, состоящую из сегментов (точек). Его форма задаётся массивом точек и может динамически меняться, что мы и используем для анимации.
В методе preload загружаются два изображения: фон и текстура для самой верёвки.
В create мы сначала добавляем фоновое изображение, а затем создаём объект Rope. Конструктор принимает начальные координаты, ключ текстуры, опорную точку (здесь null, что означает центр) и количество сегментов.
this.rope = this.add.rope(400, 300, 'banner', null, 20);
После создания объект rope содержит массив points из 20 элементов, определяющих его форму.
Применение и настройка фильтра свечения
Phaser 3 предоставляет систему пост-обработки — фильтры. Чтобы применить их к объекту, нужно сначала активировать слот для фильтров с помощью метода enableFilters(), а затем добавить нужный фильтр.
Фильтр GlowFilter создаёт эффект внешнего или внутреннего свечения. Мы добавляем его через менеджер внешних фильтров filters.external.
const fx = this.rope.enableFilters().filters.external.addGlow(0xffffff, 4, 0, 1, false, 10, 32);
Разберём параметры:
1. 0xffffff — цвет свечения (белый).
2. `4` — расстояние размытия (в пикселях).
3. `0` — качество размытия.
4. `1` — сила внутреннего свечения.
5. false — отключение режима knockout (когда объект становится невидимым, остаётся только свечение).
6. 10 — сила внешнего свечения.
7. 32 — количество шагов для отрисовки градиента свечения (качество).
Сразу после создания мы запускаем твин для параметра outerStrength, чтобы сила внешнего свечения пульсировала.
this.tweens.add({
targets: fx,
outerStrength: 10,
yoyo: true,
loop: -1,
ease: 'sine.inout'
});
Динамическое обновление геометрии в update
Вся магия движения верёвки происходит в методе update, который вызывается на каждом кадре. Мы изменяем координату `yкаждой точки в массивеthis.rope.points` по синусоидальному закону.
Переменная this.count увеличивается каждый кадр, создавая постоянное смещение фазы волны.
this.count += 0.1;
let points = this.rope.points;
for (let i = 0; i < points.length; i++)
{
points[i].y = Math.sin(i * 0.5 + this.count) * 16;
}
Здесь i * 0.5 определяет частоту волны вдоль верёвки, а * 16 — её амплитуду.
После изменения координат точек необходимо вручную сообщить системе рендеринга, что объект изменился. Для этого вызывается метод setDirty().
this.rope.setDirty();
Без этого вызова визуальная форма Rope не обновится, хотя данные в массиве точек изменятся.
Конфигурация игры и запуск
Пример завершается стандартной для Phaser 3 конфигурацией игры. В объекте config мы задаём тип рендерера, размеры холста, цвет фона, ID родительского HTML-элемента и класс нашей сцены Example.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Инициализация игры с этой конфигурацией автоматически создаст экземпляр нашей сцены и запустит игровой цикл.
Что попробовать дальше
Комбинирование динамической геометрии объекта Rope с анимированными фильтрами пост-обработки открывает широкие возможности для создания сложных визуальных эффектов с минимальным кодом. Для экспериментов попробуйте:
1. Изменить форму волны в update, используя Math.cos или комбинацию функций.
2. Анимировать другие параметры фильтра, например, innerStrength или color.
3. Привязать изменение параметров свечения к положению мыши или игровым событиям.
4. Использовать текстуру с альфа-каналом для более сложных форм верёвки.
