О чем этот пример
Визуальные эффекты — это сердце игровой атмосферы. В этом примере мы покажем, как использовать объект `RenderTexture` для создания динамического следа из «искр», который следует за курсором или персонажем. Этот подход эффективнее, чем создание сотен отдельных спрайтов, так как мы рисуем кадры в одну текстуру, что снижает нагрузку на рендеринг. Вы научитесь управлять прозрачностью, цветом и геометрией отрисовки в реальном времени.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
player;
rnd;
rt;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('dude', 'assets/sprites/phaser-dude.png');
}
create ()
{
this.rt = this.make.renderTexture({ x: 0, y: 0, width: 800, height: 600 });
this.player = this.add.sprite(256, 256, 'dude').setOrigin(0.5, 0.5);
this.rnd = Math.random;
}
update ()
{
this.player.setPosition(this.input.x, this.input.y);
this.draw();
}
draw ()
{
this.rt.clear().render();
this.rt.alpha = this.rnd();
this.rt.tint = (0xFFFFFF << this.rnd() * 8092);
for (let i = 0; i < 5; i++)
{
const rot = Math.floor((this.rnd() * Math.PI * 2) + 1);
const dist = 75 + Math.floor((this.rnd() * 50) + 1);
const x = this.player.x + dist * Math.cos(rot);
const y = this.player.y + dist * Math.sin(rot);
this.rt.draw('dude', x, y).render();
}
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example,
width: 800,
height: 600
};
const game = new Phaser.Game(config);
Подготовка сцены и создание Render Texture
В методе preload загружается спрайт для эффекта. Ключевой объект создается в create. RenderTexture — это специальный игровой объект, который действует как динамический холст. Мы можем рисовать на нем другие игровые объекты или текстуры, а затем отображать его как единое целое.
this.rt = this.make.renderTexture({ x: 0, y: 0, width: 800, height: 600 });
this.player = this.add.sprite(256, 256, 'dude').setOrigin(0.5, 0.5);
Здесь this.make.renderTexture создает текстуру размером с игровое окно (800x600). Спрайт player изначально позиционируется в центре и будет следовать за курсором. setOrigin(0.5, 0.5) центрирует точку вращения и отрисовки спрайта.
Основной цикл и позиционирование
В методе update каждый кадр мы обновляем позицию спрайта player, привязывая ее к координатам курсора мыши или касания.
this.player.setPosition(this.input.x, this.input.y);
this.draw();
this.input.x и this.input.y предоставляют текущие координаты указателя. После обновления позиции вызывается пользовательский метод draw, который отвечает за визуализацию эффекта искр.
Рисование динамического эффекта искр
Метод draw — это ядро эффекта. Каждый вызов начинается с очистки текстуры от предыдущего кадра.
this.rt.clear().render();
Метод clear() стирает все, что было нарисовано на RenderTexture, а render() применяет это изменение. Далее задаются случайные значения прозрачности и цвета для всей текстуры, что создает мерцающий эффект.
this.rt.alpha = this.rnd();
this.rt.tint = (0xFFFFFF << this.rnd() * 8092);
this.rt.alpha устанавливает общую прозрачность (от 0 до 1). this.rt.tint применяет цветовой оттенок. Сдвиг битов << и умножение на случайное число генерируют широкий спектр цветов из белого базового цвета 0xFFFFFF.
Генерация частиц по окружности
Затем в цикле создаются пять «искр». Их позиции рассчитываются случайным образом на окружности вокруг спрайта player.
for (let i = 0; i < 5; i++) {
const rot = Math.floor((this.rnd() * Math.PI * 2) + 1);
const dist = 75 + Math.floor((this.rnd() * 50) + 1);
const x = this.player.x + dist * Math.cos(rot);
const y = this.player.y + dist * Math.sin(rot);
this.rt.draw('dude', x, y).render();
}
Переменная rot — это случайный угол в радианах (от 0 до 2π). dist — случайное расстояние от центра в диапазоне от 75 до 125 пикселей. Используя тригонометрические функции Math.cos и Math.sin, вычисляются конечные координаты `xиy. Методthis.rt.drawрисует текстуру 'dude' в этих координатах наRenderTexture, аrender()` немедленно применяет отрисовку.
Что попробовать дальше
Использование RenderTexture для создания частичных эффектов — это мощная и производительная техника. Она позволяет создавать сложную динамическую графику без необходимости управлять множеством отдельных игровых объектов. Для экспериментов попробуйте изменить количество частиц в цикле, формулу распределения, добавьте масштабирование или вращение для каждой «искры», используя дополнительные параметры метода draw. Также можно накапливать след, убрав вызов clear(), или применить к текстуре шейдер для дополнительных визуальных искажений.
