О чем этот пример
Render Texture — мощный инструмент в Phaser, позволяющий рисовать игровые объекты в текстуру, а затем работать с ней как с изображением. В этой статье мы разберем пример, где одна рендер-текстура используется как источник для другой. Этот прием открывает возможности для создания эффектов постобработки, динамических масок, мини-карт и многослойного рендеринга без прямого воздействия на основной канвас.
Версия 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('bunny', 'assets/sprites/bunny.png');
}
create ()
{
const rt1 = this.add.renderTexture(0, 0, 400, 600).setOrigin(0, 0);
for (let i = 0; i < 16; i++)
{
const x = Phaser.Math.Between(-200, 400);
const y = Phaser.Math.Between(-100, 600);
rt1.draw('bunny', x, y);
}
rt1.render();
const rt2 = this.add.renderTexture(400, 0, 400, 600).setOrigin(0, 0);
rt2.draw(rt1, 0, 0).render();
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Что такое Render Texture?
Рендер-текстура (RenderTexture) — это специальный игровой объект, представляющий собой динамически создаваемое изображение в памяти. В него можно отрисовывать (draw) другие объекты: спрайты, тайловые карты, тексты и даже другие рендер-текстуры. Это похоже на временный холст или буфер.
Ключевой момент: после добавления объектов в рендер-текстуру с помощью метода draw(), необходимо вызвать метод render(), чтобы зафиксировать все изменения и сделать текстуру видимой.
Создание и наполнение первой текстуры (rt1)
В примере сначала создается рендер-текстура rt1. Она размещается в левой половине экрана (координаты 0,0) и имеет размер 400x600 пикселей.
const rt1 = this.add.renderTexture(0, 0, 400, 600).setOrigin(0, 0);
Затем в цикле метод draw() добавляет 16 случайных спрайтов «bunny» в произвольных позициях внутри области текстуры (и даже за ее пределами, что допустимо).
for (let i = 0; i < 16; i++)
{
const x = Phaser.Math.Between(-200, 400);
const y = Phaser.Math.Between(-100, 600);
rt1.draw('bunny', x, y);
}
После добавления всех спрайтов вызывается rt1.render(). Без этого вызова rt1 останется пустой на экране.
Копирование содержимого в вторую текстуру (rt2)
Далее создается вторая рендер-текстура rt2 в правой половине экрана (координата x=400).
const rt2 = this.add.renderTexture(400, 0, 400, 600).setOrigin(0, 0);
Самая интересная часть кода — отрисовка первой текстуры во вторую. В метод draw() вторым параметром можно передать не только ключ изображения, но и сам игровой объект rt1.
rt2.draw(rt1, 0, 0).render();
Здесь rt1 отрисовывается в rt2 с координатами (0,0). Методы draw() и render() можно вызывать цепочкой. В итоге мы получаем зеркальную копию левой сцены в правой части.
Практическое применение техники
Почему это полезно? Потому что rt1 теперь — это не просто набор спрайтов, а единая текстура. С ней можно делать то, что сложно или накладно делать с отдельными объектами:
* **Применение шейдеров/фильтров:** Можно применить фильтр (например, размытие или инверсию цвета) ко всей сцене, нарисованной в rt1, перед отображением в rt2.
* **Создание мини-карты:** В rt1 можно нарисовать упрощенное представление уровня, а в rt2 — уменьшенную его копию в углу экрана.
* **Динамические маски и порталы:** Содержимое rt1 можно использовать как маску или отображать через другую геометрию.
* **Оптимизация:** Сложная статическая сцена, отрендеренная один раз в текстуру, может быть отрисована за один вызов, что иногда эффективнее, чем рендеринг сотен отдельных спрайтов каждый кадр.
Что попробовать дальше
Работа с рендер-текстурами как с объектами для отрисовки открывает путь к сложным визуальным эффектам и оптимизациям в Phaser. Экспериментируйте: попробуйте применить к rt2 фильтр (Blur, Glow) после копирования rt1. Или создайте цепочку из нескольких текстур, где каждая последующая искажает предыдущую. Можно также рисовать в текстуру не спрайты, а частицы или тайловые слои, создавая уникальные композиции.
