О чем этот пример
Render Texture (текстура рендера) — это мощный инструмент в Phaser 3, который позволяет работать с графикой как с динамическим холстом. В отличие от статичного спрайта, содержимое Render Texture можно очищать, перерисовывать и трансформировать каждый кадр. В этой статье мы разберем практический пример, где простая нарисованная звезда обретает жизнь, вращаясь внутри собственного текстурированного пространства. Этот подход открывает двери для создания сложных визуальных эффектов, динамических интерфейсов и нестандартных анимаций без необходимости вручную пересчитывать координаты каждой фигуры.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
graphics;
rt;
create ()
{
this.graphics = this.add.graphics();
this.graphics.setVisible(false);
this.drawStar(this.graphics, 200, 200, 5, 200, 100, 0xffff00);
this.rt = this.add.renderTexture(400, 300, 400, 400).setOrigin(0.5);
}
update ()
{
this.rt.camera.rotation -= 0.01;
this.rt.clear();
this.rt.draw(this.graphics);
this.rt.render();
}
drawStar (graphics, cx, cy, spikes, outerRadius, innerRadius, color)
{
let rot = Math.PI / 2 * 3;
let x = cx;
let y = cy;
const step = Math.PI / spikes;
graphics.fillStyle(color, 1.0);
graphics.beginPath();
graphics.moveTo(cx, cy - outerRadius);
for (let i = 0; i < spikes; i++)
{
x = cx + Math.cos(rot) * outerRadius;
y = cy + Math.sin(rot) * outerRadius;
graphics.lineTo(x, y);
rot += step;
x = cx + Math.cos(rot) * innerRadius;
y = cy + Math.sin(rot) * innerRadius;
graphics.lineTo(x, y);
rot += step;
}
graphics.lineTo(cx, cy - outerRadius);
graphics.closePath();
graphics.fillPath();
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и создание объектов
В методе create() инициализируются два ключевых объекта: Graphics и Render Texture.
Объект Graphics — это инструмент для векторного рисования. Мы создаем его, но сразу делаем невидимым, так как он будет служить лишь шаблоном или «кистью» для отрисовки.
this.graphics = this.add.graphics();
this.graphics.setVisible(false);
Затем с помощью вспомогательного метода drawStar на объекте graphics рисуется желтая пятиконечная звезда. Ее координаты (200, 200) задаются относительно самого объекта Graphics, а не сцены.
Следующим шагом создается сама Render Texture. Это специальный игровой объект, который представляет собой область в памяти (холст) для рендеринга.
this.rt = this.add.renderTexture(400, 300, 400, 400).setOrigin(0.5);
Здесь мы создаем текстуру размером 400x400 пикселей, позиционируем ее в центре сцены (400, 300) и устанавливаем точку вращения (origin) в ее центр.
Цикл обновления: анимация через управление камерой
Вся магия происходит в методе update(), который выполняется каждый кадр. Ключевой момент: у Render Texture есть своя собственная камера (this.rt.camera). Вращая эту камеру, мы меняем «точку обзора» на содержимое текстуры, что создает эффект вращения самой отрисованной графики.
this.rt.camera.rotation -= 0.01;
Перед тем как что-то нарисовать заново, необходимо очистить текстуру от содержимого предыдущего кадра. Для этого используется метод .clear().
this.rt.clear();
Рисование и финальный рендер
После очистки мы «штампуем» нашу заранее нарисованную звезду (объект graphics) на холст Render Texture. Важно понимать: мы рисуем не сам объект Graphics, а его визуальное представление (то, что было нарисовано в нем методами fillStyle, beginPath и т.д.).
this.rt.draw(this.graphics);
Метод draw() может принимать не только Graphics, но и другие объекты, например, спрайты или тексты.
Финальный шаг — вызов .render(). Этот метод явно указывает движку, что все операции отрисовки для данной текстуры завершены и ее нужно визуализировать. Без этого вызова изменения могут не отобразиться на экране.
this.rt.render();
Таким образом, каждый кадр мы: 1) поворачиваем камеру текстуры, 2) очищаем ее, 3) рисуем звезду в новом положении камеры и 4) выводим результат на экран.
Вспомогательная функция drawStar
Это классическая функция для рисования звезды с использованием тригонометрии. Она работает непосредственно с API объекта Graphics.
- cx, cy: центральная точка звезды.
- spikes: количество лучей.
- outerRadius, innerRadius: радиусы вершин и впадин лучей.
- color: цвет заливки.
Функция последовательно вычисляет точки луча звезды, используя Math.cos и Math.sin, и соединяет их линиями, формируя путь (path), который затем заливается цветом.
graphics.fillStyle(color, 1.0);
graphics.beginPath();
graphics.moveTo(cx, cy - outerRadius);
// ... вычисление и отрисовка точек
graphics.closePath();
graphics.fillPath();
Что попробовать дальше
Render Texture — это гибридный объект, сочетающий в себе свойства статичной текстуры и динамичного контейнера. В рассмотренном примере мы отделили процесс создания сложной векторной формы (отрисовка звезды) от процесса ее анимации (вращение камеры текстуры). Для экспериментов попробуйте
- рисовать в текстуру несколько разных объектов
Graphics - анимировать не только вращение камеры, но и ее масштаб (
this.rt.camera.zoom) - использовать
this.rt.saveTexture('key')для сохранения результата рендера в текстуру кэша и последующего применения к спрайту
