Процедурная генерация текстур в Phaser позволяет создавать динамические графические элементы во время выполнения игры без необходимости хранить их в виде файлов. Это особенно полезно для спрайтов, фонов, частиц, тайловых карт и UI-элементов, когда требуется разнообразие или экономия памяти.
В Phaser 3 основной инструмент для таких задач — объект Graphics и методы класса TextureManager, который управляет текстурами.
Phaser.GameObjects.Graphics позволяет рисовать примитивы
(прямоугольники, окружности, линии, полигоны) и сохранять их в
текстуры.
Пример базового подхода:
const graphics = this.add.graphics();
// Настройка заливки и линии
graphics.fillStyle(0xff0000, 1); // красная заливка
graphics.lineStyle(2, 0x000000, 1); // черная линия
// Рисование прямоугольника
graphics.strokeRect(50, 50, 100, 100);
graphics.fillRect(50, 50, 100, 100);
// Сохранение графики в текстуру
graphics.generateTexture('redBox', 200, 200);
graphics.destroy(); // после генерации можно удалить объект
Ключевой момент: метод generateTexture создает
имя текстуры, которую можно использовать как обычный
спрайт:
this.add.image(400, 300, 'redBox');
Это позволяет создавать текстуры динамически, в зависимости от игровых условий.
Процедурная генерация раскрывается, когда используется случайная генерация. Для имитации естественных объектов (камни, травинка, облака) применяют методы случайного распределения и шумовые алгоритмы.
Пример создания текстуры с шумом:
const width = 128;
const height = 128;
const graphics = this.add.graphics();
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
const value = Math.floor(Math.random() * 256);
graphics.fillStyle((value << 16) | (value << 8) | value, 1);
graphics.fillRect(x, y, 1, 1);
}
}
graphics.generateTexture('noise', width, height);
graphics.destroy();
В результате получается текстура, где каждый пиксель имеет случайный оттенок серого. Это базовый пример пиксельного шума, который можно использовать для создания эффекта дыма, воды или текстурной подложки.
Иногда Graphics не подходит для сложных
вычислительных операций на пикселях, например для фильтров или
генерации градиентов с искажениями. В этом случае используют
CanvasTexture.
const texture = this.textures.createCanvas('gradient', 256, 256);
const ctx = texture.getContext();
const gradient = ctx.createLinearGradient(0, 0, 256, 256);
gradient.addColorStop(0, '#ff0000');
gradient.addColorStop(1, '#0000ff');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 256, 256);
texture.refresh(); // обновление текстуры для использования в спрайте
this.add.image(400, 300, 'gradient');
CanvasTexture позволяет использовать весь API HTML5
Canvas, включая кривые Безье, фильтры, градиенты и пиксельные
манипуляции, что делает возможным генерацию сложных текстур, аналогичных
программной графике.
Процедурная генерация может применяться для анимации, когда текстура обновляется каждый кадр:
const texture = this.textures.createCanvas('animatedNoise', 128, 128);
const ctx = texture.getContext();
this.time.addEvent({
delay: 50,
loop: true,
callback: () => {
for (let x = 0; x < 128; x++) {
for (let y = 0; y < 128; y++) {
const value = Math.floor(Math.random() * 256);
ctx.fillStyle = `rgb(${value},${value},${value})`;
ctx.fillRect(x, y, 1, 1);
}
}
texture.refresh();
}
});
Такой подход используется для создания эффекта огня, дыма, искр или
воды. Основной принцип: каждое обновление CanvasTexture сопровождается
вызовом refresh().
drawImage и
CanvasRenderingContext2D.putImageData позволяют обновлять
части текстуры, что ускоряет работу.Процедурная генерация в Phaser обеспечивает гибкость и динамичность графики, снижает зависимость от ассетов и открывает возможности для уникального визуального стиля игры.