О чем этот пример
Render Texture (текстура рендеринга) в Phaser — это мощный холст в памяти, на котором можно рисовать, копировать и, что особенно интересно, стирать другие игровые объекты. Эта техника открывает двери для создания динамических поверхностей, интерактивных фонов или мини-игр по рисованию, где игрок может "соскабливать" слой, открывая изображение под ним. В этой статье мы разберем пример, где текстура травы рисуется на Render Texture, а затем стирается курсором мыши, обнажая фоновую картинку. Вы научитесь создавать такие интерактивные элементы и понимать, как управлять пикселями в реальном времени.
Версия 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('brush', 'assets/particles/sparkle1.png');
this.load.image('tiles', 'assets/textures/grass.png');
this.load.image('bg', 'assets/pics/turkey-1985086.jpg');
}
create ()
{
this.add.image(0, 0, 'bg').setOrigin(0);
const rt = this.add.renderTexture(400, 300, 800, 600);
for (let y = 0; y < 2; y++)
{
for (let x = 0; x < 2; x++)
{
rt.draw('tiles', x * 512 + 256, y * 512 + 256);
}
}
rt.render();
const brush = this.make.image({ key: 'brush' }, false).setScale(1);
this.input.on('pointermove', pointer =>
{
if (pointer.isDown)
{
rt.erase(brush, pointer.x - 16, pointer.y - 16).render();
}
}, this);
this.input.on('pointerdown', pointer =>
{
rt.erase(brush, pointer.x - 16, pointer.y - 16).render();
}, this);
}
}
const config = {
type: Phaser.CANVAS,
parent: 'phaser-example',
width: 800,
height: 600,
backgroundColor: '#2d2d88',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и создание Render Texture
В методе preload загружаются три изображения: кисть (brush) для стирания, тайловая текстура (tiles) для верхнего слоя и фоновая картинка (bg).
В create первым делом фоновая картинка добавляется на сцену с координатами (0,0) и началом в левом верхнем углу.
Затем создается объект RenderTexture. Это ключевой элемент. Он представляет собой невидимый холст заданного размера (800x600), расположенный в точке (400,300). На этом холсте мы и будем рисовать.
const rt = this.add.renderTexture(400, 300, 800, 600);
Заполнение Render Texture тайлами
Чтобы Render Texture стала видимой и заполнила пространство, на нее нужно что-то нарисовать. В примере используется двойной цикл for, который рисует текстуру травы (tiles) четыре раза, создавая сетку 2x2. Метод draw добавляет изображение в указанные координаты на Render Texture. Координаты 256 и 512 подобраны так, чтобы тайлы выровнялись по центру и образовали бесшовное покрытие.
После рисования необходимо вызвать метод render(), чтобы все отложенные операции рисования применились и изменения стали видны на экране.
for (let y = 0; y < 2; y++)
{
for (let x = 0; x < 2; x++)
{
rt.draw('tiles', x * 512 + 256, y * 512 + 256);
}
}
rt.render();
Создание кисти для стирания
Для операции стирания нужна кисть — изображение, которое будет определять форму и область стирания. В примере кисть создается через this.make.image. Важный момент: второй аргумент false указывает, что этот объект не должен автоматически добавляться на дисплейный список сцены. Он существует только в памяти как шаблон для операции erase. Масштаб кисти установлен в 1.
const brush = this.make.image({ key: 'brush' }, false).setScale(1);
Интерактивное стирание по движению мыши
Вся магия происходит в обработчиках событий ввода. Phaser предоставляет два события: pointerdown (кнопка мыши нажата) и pointermove (курсор перемещается).
Внутри этих обработчиков проверяется, нажата ли кнопка мыши (pointer.isDown). Если да, то вызывается ключевой метод rt.erase(). Этот метод принимает кисть (brush) и координаты (X, Y), куда ее нужно применить. В примере координаты корректируются на половину размера кисти (-16), чтобы центр кисти совпадал с позицией курсора.
Метод erase не применяет изменения моментально. Как и draw, он требует последующего вызова render(), чтобы обновить визуальное представление Render Texture. После стирания часть текстуры травы становится прозрачной, и сквозь нее проступает фоновая картинка, создавая эффект "соскабливания".
this.input.on('pointermove', pointer =>
{
if (pointer.isDown)
{
rt.erase(brush, pointer.x - 16, pointer.y - 16).render();
}
}, this);
this.input.on('pointerdown', pointer =>
{
rt.erase(brush, pointer.x - 16, pointer.y - 16).render();
}, this);
Что попробовать дальше
Render Texture с методами draw и erase — это гибкий инструмент для работы с пикселями в реальном времени. Вы можете использовать эту технику не только для рисования, но и для создания динамических масок, интерактивных элементов интерфейса или нестандартных переходов между сценами.
Попробуйте поэкспериментировать: измените изображение кисти на что-то большее или с градиентом прозрачности, чтобы стирание было не резким, а плавным. Используйте rt.fill для заливки цветом или rt.clear для полной очистки холста. Комбинируя эти методы, можно создавать по-настоящему уникальные игровые механики.
