Создание текстуры из Canvas

В библиотеке Phaser возможность создавать текстуры на лету с помощью Canvas открывает широкие возможности для динамической графики, процедурной генерации объектов и кастомных эффектов. Canvas предоставляет прямой доступ к пиксельным данным и методам рисования 2D, что позволяет создавать сложные спрайты без необходимости использования готовых изображений.


Инициализация текстуры через Canvas

Для создания текстуры из Canvas используется объект Phaser.Textures.CanvasTexture. Основная последовательность действий:

  1. Создание текстуры в менеджере текстур сцены:
let canvasTexture = this.textures.createCanvas('myCanvas', 256, 256);
  • 'myCanvas' — уникальный ключ текстуры.
  • 256, 256 — размеры холста в пикселях.
  1. Получение контекста рисования:
let ctx = canvasTexture.getContext();

Контекст (ctx) является стандартным CanvasRenderingContext2D, что позволяет использовать все методы рисования HTML5 Canvas.

  1. Применение рисунка или заливки:
ctx.fillStyle = '#ff0000';
ctx.fillRect(0, 0, 256, 256);
  1. Обновление текстуры для сцены:
canvasTexture.refresh();

Метод refresh() обязателен после изменения контекста, иначе внесённые изменения не отобразятся в Phaser.


Применение Canvas-текстуры к игровым объектам

Созданную текстуру можно использовать как спрайт или любой другой объект, поддерживающий текстуры:

let sprite = this.add.image(400, 300, 'myCanvas');

Преимущество подхода заключается в возможности изменять текстуру динамически, что особенно полезно для:

  • процедурной генерации карт;
  • визуализации данных в реальном времени;
  • динамических эффектов, таких как пули, взрывы, частицы.

Динамическое обновление текстур

Canvas-текстуры в Phaser можно обновлять на каждом кадре. Например, анимация движения объекта внутри Canvas:

let canvasTexture = this.textures.createCanvas('dynamicCanvas', 128, 128);
let ctx = canvasTexture.getContext();
let x = 0;

this.time.addEvent({
    loop: true,
    callback: () => {
        ctx.clearRect(0, 0, 128, 128);
        ctx.fillStyle = '#00ff00';
        ctx.beginPath();
        ctx.arc(x, 64, 20, 0, Math.PI * 2);
        ctx.fill();
        canvasTexture.refresh();
        x += 2;
        if (x > 128) x = 0;
    }
});
this.add.image(400, 300, 'dynamicCanvas');

Ключевой момент: вызов refresh() после каждого изменения является обязательным для отражения изменений на сцене.


Использование Canvas для процедурной графики

Canvas позволяет создавать графику по алгоритмам без готовых ресурсов. Примеры применения:

  1. Генерация шумовой текстуры
let canvasTexture = this.textures.createCanvas('noise', 128, 128);
let ctx = canvasTexture.getContext();

for (let i = 0; i < 128; i++) {
    for (let j = 0; j < 128; j++) {
        let gray = Math.floor(Math.random() * 256);
        ctx.fillStyle = `rgb(${gray},${gray},${gray})`;
        ctx.fillRect(i, j, 1, 1);
    }
}
canvasTexture.refresh();
this.add.image(400, 300, 'noise');
  1. Рисование градиентов и сложных фигур
let canvasTexture = this.textures.createCanvas('gradient', 200, 200);
let ctx = canvasTexture.getContext();
let gradient = ctx.createLinearGradient(0, 0, 200, 200);
gradient.addColorStop(0, 'blue');
gradient.addColorStop(1, 'yellow');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 200, 200);
canvasTexture.refresh();
this.add.image(400, 300, 'gradient');
  1. Создание динамических эффектов частиц Используя Canvas, можно нарисовать спрайт частицы с изменяемыми цветами и формой и затем использовать его в Phaser.GameObjects.Particles.ParticleEmitter.

Оптимизация при работе с Canvas-текстурами

  • Размер текстуры: избегать создания слишком больших Canvas, так как это увеличивает нагрузку на GPU.
  • Минимизация вызовов refresh(): обновлять текстуру только при реальной необходимости.
  • Использование clearRect вместо создания нового Canvas: снижает количество аллокаций памяти.
  • Кэширование промежуточных рисунков: при повторяющихся графических элементах целесообразно хранить их в отдельных Canvas и повторно использовать.

Интеграция с другими объектами Phaser

Canvas-текстуры совместимы с:

  • Image и Sprite — для статичных и анимированных объектов;
  • TileSprite — для создания динамически изменяемых фонов;
  • RenderTexture — для сложных композиций, где Canvas может использоваться как промежуточный слой.

Прямой доступ к пикселям через getImageData и putImageData позволяет реализовывать:

  • фильтры и размытия;
  • пиксельные эффекты разрушения объектов;
  • динамическое окрашивание текстур.

Особенности использования

  • Canvas-текстуры являются частью менеджера текстур сцены, поэтому они существуют только в рамках сцены, где были созданы. Для использования между сценами нужно передавать ключ и копировать текстуру.
  • При масштабировании Canvas-объектов важно учитывать соотношение сторон, так как растягивание может вызвать размытие.
  • Методы Canvas доступны в Phaser в полном объёме, что позволяет интегрировать любые алгоритмы рисования из стандартного HTML5 Canvas в игровой процесс.

Эта функциональность делает Phaser мощным инструментом для генеративной графики, динамических эффектов и визуализации данных, предоставляя прямой контроль над пикселями и возможность создания уникальных игровых объектов без зависимости от внешних ресурсов.