О чем этот пример
Один из мощнейших инструментов Phaser для оптимизации и создания динамического визуального контента — Render Texture. Эта техника позволяет рисовать различные игровые объекты в буфер в памяти, а затем сохранять результат как отдельную текстуру. Это особенно полезно для создания сложных спрайтов из нескольких частей, кэширования статических элементов интерфейса или, как в нашем примере, генерации составного изображения для массового использования. Вместо сотни отдельных вызовов отрисовки для каждого объекта мы создаём текстуру один раз и используем её многократно, что снижает нагрузку на рендерер.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
rt;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bubble', 'assets/particles/bubble.png');
this.load.image('dude', 'assets/sprites/phaser-dude.png');
}
create ()
{
this.rt = this.make.renderTexture({ width: 100, height: 100 }, false);
this.rt.draw('bubble', 50, 50);
this.rt.draw('dude', 50, 50);
this.rt.render();
const t = this.rt.saveTexture('bubbleboy');
for (let i = 0; i < 100; i++)
{
this.add.image(Phaser.Math.Between(100, 700), Phaser.Math.Between(100, 500), 'bubbleboy');
}
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
backgroundColor: '#2d2d88',
scene: Example
};
const game = new Phaser.Game(config);
Что такое Render Texture?
Класс Phaser.GameObjects.RenderTexture — это специальный игровой объект, который выступает в роли холста или буфера в памяти. Вы можете отрисовывать на нём другие игровые объекты (изображения, спрайты, текст), но сам он невидим для игрока. Его основная цель — служить промежуточным этапом для создания графики.
В нашем примере мы создаём Render Texture размером 100x100 пикселей. Ключевой параметр false в конструкторе указывает, что текстура не будет добавлена на дисплейный список сцены автоматически. Она существует только в памяти.
Рисование и сохранение текстуры
После создания буфера мы наполняем его содержимым, используя метод .draw(). Этот метод принимает ключ текстуры и координаты для отрисовки относительно левого верхнего угла Render Texture.
this.rt.draw('bubble', 50, 50);
this.rt.draw('dude', 50, 50);
Здесь мы сначала рисуем изображение пузыря (bubble), а затем поверх него — спрайт персонажа (dude). Оба рисуются в центре нашей текстуры (50, 50).
Метод .render() финализирует все операции рисования в буфере. После этого критически важный шаг — метод .saveTexture(). Он берёт текущее содержимое Render Texture и регистрирует его в текстовом менеджере игры (this.textures) под новым, заданным вами ключом. Теперь к этому составному изображению можно обращаться как к любой другой загруженной текстуре.
const t = this.rt.saveTexture('bubbleboy');
Массовое использование созданной текстуры
После того как текстура 'bubbleboy' сохранена, её можно использовать бесконечное количество раз, создавая стандартные объекты Image. В примере это демонстрируется циклом, который создаёт 100 таких изображений в случайных позициях на экране.
for (let i = 0; i < 100; i++)
{
this.add.image(Phaser.Math.Between(100, 700), Phaser.Math.Between(100, 500), 'bubbleboy');
}
С точки зрения производительности это крайне эффективно. Движок не отрисовывает для каждого из ста объектов комбинацию пузыря и персонажа. Вместо этого он рисует одну и ту же, уже готовую текстуру, что значительно быстрее. Это классический приём для оптимизации отрисовки множества однотипных или составных объектов: частицы, тайлы, элементы окружения.
Конфигурация сцены и игры
Код примера завершается стандартной для Phaser конфигурацией. Обратите внимание, что фон сцены (backgroundColor) задан тёмно-синим, чтобы созданные белые изображения хорошо контрастировали.
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
backgroundColor: '#2d2d88',
scene: Example
};
const game = new Phaser.Game(config);
Инициализация игры с этой конфигурацией запускает нашу сцену Example, где и происходит вся магия с Render Texture.
Что попробовать дальше
Render Texture с последующим сохранением в saveTexture — это мощный дуэт для динамического создания ресурсов игры прямо во время её выполнения. Вы можете комбинировать анимации, текст, эффекты и сохранять результат как статичную текстуру для повторного использования.
**Идеи для экспериментов:**
1. Попробуйте рисовать на Render Texture не статичные изображения, а анимированные спрайты (this.rt.drawFrame('spriteKey', frameName)), чтобы запечатлеть определённый кадр.
2. Используйте графические примитивы (this.rt.fillRect, this.rt.strokeCircle) из контекста RenderTexture для программного создания текстур интерфейса (кнопок, панелей).
3. Поэкспериментируйте с альфа-каналом и blend-режимами при рисовании, чтобы создавать сложные полупрозрачные комбинации.
