О чем этот пример
Классическая анимация по ключевым точкам даёт предсказуемый, но скучный результат. В игровых эффектах — от магических следов до искр — частицы должны двигаться плавно и с характером. В Phaser Particle Emitter для этого есть встроенная интерполяция. Эта статья покажет, как с помощью всего одного параметра конфигурации вы можете заставить частицы лететь по линейной траектории, изящной кривой Безье или сглаженному пути Catmull-Rom. Вы научитесь динамически переключать типы движения в реальном времени, что откроет возможности для создания сложных и разнообразных визуальных эффектов из одного набора данных.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('red', 'assets/particles/red.png');
this.load.image('green', 'assets/particles/green.png');
this.load.image('blue', 'assets/particles/blue.png');
}
create ()
{
let i = 0;
this.linear = this.add.particles(0, 100, 'red', {
x: { values: [ 50, 500, 200, 800 ], interpolation: 'linear' },
lifespan: 2500,
gravityY: 120,
speed: 16,
scale: 0.65,
blendMode: 'ADD'
});
this.bezier = this.add.particles(0, 100, 'green', {
x: { values: [ 50, 500, 200, 800 ], interpolation: 'bezier' },
lifespan: 2500,
gravityY: 120,
speed: 16,
scale: 0.65,
emitting: false,
blendMode: 'ADD'
});
this.catmull = this.add.particles(0, 100, 'blue', {
x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull' },
lifespan: 2500,
gravityY: 120,
speed: 16,
scale: 0.65,
emitting: false,
blendMode: 'ADD'
});
this.add.text(10, 10, 'Click to change interpolation type');
const type = this.add.text(10, 40, 'x pos interpolation: linear');
this.input.on('pointerdown', () => {
i++;
if (i === 1)
{
this.linear.emitting = false;
this.bezier.emitting = true;
type.setText('x pos interpolation: bezier');
}
else if (i === 2)
{
this.bezier.emitting = false;
this.catmull.emitting = true;
type.setText('x pos interpolation: catmull rom');
}
else if (i === 3)
{
this.catmull.emitting = false;
this.linear.emitting = true;
type.setText('x pos interpolation: linear');
i = 0;
}
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и создание эмиттеров
В методе preload загружаются три текстуры для частиц разного цвета. В create создаются три независимых эмиттера частиц (this.linear, this.bezier, this.catmull), которые изначально расположены на одной линии по оси Y (y = 100). Ключевое отличие между ними — параметр interpolation в свойстве `x`.
Каждый эмиттер получает один и тот же массив значений для координаты X: [50, 500, 200, 800]. Частицы будут появляться и двигаться, последовательно проходя через эти точки на экране, но тип движения между ними будет разным.
this.linear = this.add.particles(0, 100, 'red', {
x: { values: [50, 500, 200, 800], interpolation: 'linear' },
lifespan: 2500,
gravityY: 120,
speed: 16,
scale: 0.65,
blendMode: 'ADD'
});
Два из трёх эмиттеров (bezier и catmull) создаются с флагом emitting: false, чтобы изначально была активна только линейная интерполяция.
Линейная интерполяция: просто и понятно
Тип 'linear' — самый простой. Частица движется от одной ключевой точки к следующей по прямой линии с постоянной скоростью. Это создаёт чёткие, угловатые траектории, хорошо подходящие для механических или строгих эффектов, например, движения лазерного луча по заданным координатам.
Визуально это выглядит как резкая смена направления при достижении каждой точки из массива values. В примере эмиттер this.linear активен по умолчанию.
Кривая Безье: плавные изгибы
При interpolation: 'bezier' Phaser строит плавную кривую, используя ключевые точки как опорные. Движение между точками происходит не по прямой, а по изогнутой траектории, что создаёт более органичные и естественные визуальные эффекты, например, для дыма, магических потоков или летящих листьев.
Частицы будут "затекать" в ключевые точки, а не резко в них врезаться, что смягчает общее впечатление от анимации.
x: { values: [50, 500, 200, 800], interpolation: 'bezier' }
Catmull-Rom: сглаженный путь через точки
Интерполяция 'catmull' (Catmull-Rom) создаёт сплайн, который гарантированно проходит через все ключевые точки, как и линейная, но при этом имеет непрерывную кривизну. Это даёт самый плавный и "профессиональный" вид движения.
Траектория частиц выглядит как естественная, сглаженная кривая, идеально подходящая для следов за заклинаниями, полёта фей или плавного патрулирования объектов.
x: { values: [50, 500, 200, 800], interpolation: 'catmull' }
Динамическое переключение режимов
Пример реализует интерактивное переключение между типами интерполяции по клику мыши. В слушателе события 'pointerdown' увеличивается счётчик `i`, который по модульной логике (0, 1, 2, сброс) поочерёдно отключает текущий эмиттер и включает следующий.
Это демонстрирует мощный приём: вы можете иметь несколько готовых эмиттеров с разным поведением и активировать их по необходимости, не пересоздавая.
this.input.on('pointerdown', () => {
i++;
if (i === 1) {
this.linear.emitting = false;
this.bezier.emitting = true;
type.setText('x pos interpolation: bezier');
}
// ... остальные условия для catmull и сброса
});
Что попробовать дальше
Интерполяция в эмиттерах частиц Phaser — это простой, но невероятно мощный инструмент для управления движением. Меняя один параметр, вы радикально меняете характер всего визуального эффекта.
Для экспериментов попробуйте: применить интерполяцию к свойству `yилиscale; создать массив точек динамически, в зависимости от действий игрока; комбинировать разные типы интерполяции для разных свойств одного эмиттера (например,xпо'catmull', аscaleпо'linear'`) для создания ещё более сложных эффектов.
