О чем этот пример
В Phaser есть мощный инструмент для создания динамических текстур и сложных визуальных эффектов — `RenderTexture`. Эта статья покажет, как с его помощью можно использовать один игровой объект в качестве «кисти» для отрисовки на другом. Этот приём открывает дорогу к созданию кастомных систем частиц, динамических фонов или уникальных эффектов наложения спрайтов прямо во время выполнения игры, без подготовки дополнительных ассетов.
Версия 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('mushroom', 'assets/sprites/mushroom16x16.png');
}
create ()
{
const rt = this.add.renderTexture(0, 0, 800, 600).setOrigin(0);
const mushroom = this.add.image(200, 300, 'mushroom').setScale(16);
rt.draw(mushroom, 400, 0).render();
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
backgroundColor: '#2d2d88',
pixelArt: true,
scene: Example
};
const game = new Phaser.Game(config);
Что такое Render Texture?
RenderTexture — это специальный тип текстуры в Phaser, на который можно программно рисовать (рендерить) другие игровые объекты. Представьте её как пустое полноразмерное полотно (canvas) внутри вашей сцены. Вы можете добавлять на это полноцветные изображения, спрайты, группы объектов, а затем отображать итоговую текстуру в игре как единый объект.
Ключевое преимущество — вся отрисовка происходит в рантайме. Это позволяет создавать текстуры, которые реагируют на действия игрока или состояние игры, что невозможно при использовании статичных изображений, загруженных через preload.
Разбираем пример кода
Давайте разберём предоставленный пример построчно, чтобы понять логику работы.
Сначала в методе preload загружается спрайт гриба. Обратите внимание на использование setBaseURL — это удобно для указания базового пути к ассетам, особенно в демонстрационных целях.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('mushroom', 'assets/sprites/mushroom16x16.png');
В методе create происходит вся магия. Сначала создаётся объект RenderTexture (сокращённо rt), который будет занимать всю сцену (800x600 пикселей) и иметь точку привязки (origin) в левом верхнем углу.
const rt = this.add.renderTexture(0, 0, 800, 600).setOrigin(0);
Затем создаётся обычный объект Image — гриб. Он позиционируется в точке (200, 300) и масштабируется в 16 раз. Этот объект будет виден на сцене независимо от RenderTexture.
const mushroom = this.add.image(200, 300, 'mushroom').setScale(16);
Самое важное — метод draw. Он «рисует» (точнее, копирует визуальное представление) объект mushroom на текстуру rt в указанных координатах (400, 0). Вызов render() финализирует процесс отрисовки на текстуре.
rt.draw(mushroom, 400, 0).render();
В итоге на экране мы увидим два огромных гриба: один (исходный mushroom) на позиции (200, 300), а второй — его отпечаток, нарисованный на RenderTexture в позиции (400, 0).
Конфигурация сцены и важность pixelArt
Конфиг игры содержит ключевую настройку для пиксель-арт графики.
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
backgroundColor: '#2d2d88',
pixelArt: true,
scene: Example
};
Флаг pixelArt: true автоматически отключает сглаживание изображений (anti-aliasing) при их масштабировании. Это критически важно для сохранения чёткости и «блочного» вида пиксельной графики. Без этой настройки наш гриб, увеличенный в 16 раз, выглядел бы размытым. Также здесь задан красивый фоновый цвет для контраста.
Практическое применение: от теории к игре
Как можно использовать RenderTexture в реальном проекте? Вот несколько идей:
1. **Динамические следы:** Рисовать текстуру земли под ногами персонажа или следы шин за автомобилем. 2. **Кастомные эффекты затемнения/освещения:** Накладывать полупрозрачные текстуры для создания областей тени или света от фонарика. 3. **Сложные UI-элементы:** Собирать интерфейс из множества мелких спрайтов в одну текстуру для оптимизации отрисовки.
Важно помнить, что draw копирует не объект, а его текущий кадр. Для анимированного спрайта это будет текущий кадр анимации. Метод render() нужно вызывать после завершения всех операций draw для отрисовки на текстуре.
Что попробовать дальше
RenderTexture — это ваш швейцарский нож для создания динамической графики в Phaser. Он позволяет выйти за рамки статичных ассетов и наполнять игру контентом, который генерируется прямо во время игры.
**Идеи для экспериментов:** Попробуйте рисовать на текстуре в цикле или по таймеру, создавая анимацию «появления». Используйте в качестве кисти не спрайт, а целую группу (Group) объектов. Исследуйте методы clear() для стирания текстуры и saveTexture() для её сохранения в кэш текстуры игры.
