О чем этот пример
Работа с графикой на уровне отдельных пикселей открывает огромные возможности для создания уникальных визуальных эффектов в играх: от динамического разрушения ландшафта и систем частиц до стилизации под пиксель-арт и генерации процедурных текстур. В этой статье мы разберем пример из официальной документации Phaser, который демонстрирует, как получить доступ к данным изображения, извлечь цвет каждого пикселя и использовать его для создания новой композиции. Этот метод — фундамент для реализации продвинутых графических механик.
Версия 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('piggy', 'assets/pics/pigchampagne.png');
}
create ()
{
const src = this.textures.get('piggy').getSourceImage();
const canvas = this.textures.createCanvas('map', src.width, src.height).draw(0, 0, src);
// You can now access the CanvasTexture properties, such as canvas.imageData
// Here we'll just create a rectangle for each pixel, with a unique size
const pixel = new Phaser.Display.Color();
for (let y = 0; y < src.height; y++)
{
for (let x = 0; x < src.width; x++)
{
canvas.getPixel(x, y, pixel);
if (pixel.a > 0)
{
this.add.rectangle(x * 4, y * 8, 4, 8, pixel.color);
}
}
}
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Подготовка и загрузка текстуры
Первым делом в методе preload() мы загружаем изображение, с которым будем работать. Важно установить базовый URL для загрузчика, если ресурсы хранятся удаленно. В данном случае используется стандартное изображение из примеров Phaser.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('piggy', 'assets/pics/pigchampagne.png');
}
Получение источника изображения и создание холста
В методе create() начинается основная работа. Сначала мы получаем исходный DOM-элемент изображения (HTMLImageElement) через this.textures.get('piggy').getSourceImage(). Это дает доступ к "сырым" данным картинки.
Затем создается специальный CanvasTexture с именем 'map' и размерами, совпадающими с исходным изображением. Метод .draw(0, 0, src) сразу отрисовывает загруженную картинку на этот холст. Теперь у нас есть текстура Phaser, которая также является HTMLCanvasElement, что позволяет использовать контекст 2D или, как в нашем случае, работать с данными пикселей.
const src = this.textures.get('piggy').getSourceImage();
const canvas = this.textures.createCanvas('map', src.width, src.height).draw(0, 0, src);
Итерация по пикселям и извлечение цвета
Для эффективного получения цвета мы создаем один экземпляр Phaser.Display.Color. Это объект-утилита для работы с цветами, который будет переиспользоваться в цикле, что предотвращает создание тысяч одноразовых объектов.
Два вложенных цикла проходят по всем координатам изображения. Ключевой метод canvas.getPixel(x, y, pixel) записывает цвет пикселя с координатами (x, y) в переданный объект pixel. После вызова этого метода в объекте pixel доступны свойства `r,g,b,aи вычисленное целочисленное значениеcolor`.
const pixel = new Phaser.Display.Color();
for (let y = 0; y < src.height; y++)
{
for (let x = 0; x < src.width; x++)
{
canvas.getPixel(x, y, pixel);
}
}
Визуализация данных: от пикселей к прямоугольникам
Получив цвет, мы можем его использовать. В примере выполняется проверка if (pixel.a > 0), которая отсекает полностью прозрачные пиксели (альфа-канал равен 0).
Для каждого непрозрачного пикселя создается прямоугольник (this.add.rectangle). Его координаты умножены на разные коэффициенты (4 по X и 8 по Y), что растягивает итоговую композицию, создавая интересный визуальный эффект, отдаленно напоминающий исходное изображение. Цвет прямоугольника задается свойством pixel.color.
if (pixel.a > 0)
{
this.add.rectangle(x * 4, y * 8, 4, 8, pixel.color);
}
Что попробовать дальше
Этот пример — отправная точка для экспериментов с пиксельной графикой в Phaser. Попробуйте изменить форму примитивов (используйте add.circle или add.triangle), примените математические функции к координатам и размерам для создания волн, шума или паттернов. Можно реализовать эффект "разлета" пикселей при клике, сохранять модифицированные данные холста обратно в текстуру через canvas.update() или даже загружать пользовательские изображения для их последующей обработки.
