О чем этот пример
Оптимизация рендеринга — ключевой навык при разработке игр. Этот пример демонстрирует, как Phaser обрабатывает тысячи спрайтов, и знакомит с мощным методом `captureFrame` для отладки и создания скриншотов. Мы разберем, как организовать массовое создание объектов и в каких сценариях это полезно для тестирования производительности вашей игры.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload ()
{
// this.load.setBaseURL('https://cdn.phaserfiles.com/v385');
for (let i = 1; i <= 32; i++)
{
this.load.image(`pixel${i}`, `assets/tests/pixels/${i}.png`);
}
}
create ()
{
let y = 0;
let total = 0;
this.input.on('pointerdown', (pointer) => {
if (pointer.worldY >= 500)
{
console.log('Capture');
this.game.renderer.captureFrame(false, true);
}
else
{
this.addSprites(y);
y++;
total += 1024;
this.addSprites(y);
y++;
total += 1024;
this.addSprites(y);
y++;
total += 1024;
this.addSprites(y);
y++;
total += 1024;
console.log('Total sprites:', total);
}
});
}
addSprites (y)
{
let color = 1;
for (let x = 0; x < 1024; x++)
{
this.add.image(x, y, `pixel${color}`).setOrigin(0);
// color++;
if (color === 15)
{
color = 1;
}
}
}
}
const config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
width: 1024,
height: 512,
scene: Example
};
const game = new Phaser.Game(config);
Загрузка ресурсов: подготовка пикселей
В методе preload происходит загрузка 32 простейших изображений — цветных пикселей. Это типичный подход для тестов производительности, где важно исключить влияние размера и сложности текстур.
for (let i = 1; i <= 32; i++)
{
this.load.image(`pixel${i}`, `assets/tests/pixels/${i}.png`);
}
Цикл динамически формирует ключи (pixel1, pixel2 и т.д.) и пути к файлам. Эти ключи позже используются для создания спрайтов.
Интерактивность и логика создания
Вся логика в методе create привязана к событию клика (pointerdown). В зависимости от координаты клика, код либо создает новую порцию спрайтов, либо делает снимок экрана.
this.input.on('pointerdown', (pointer) => {
if (pointer.worldY >= 500)
{
console.log('Capture');
this.game.renderer.captureFrame(false, true);
}
else
{
// Создание спрайтов...
}
});
Условие pointer.worldY >= 500 проверяет, был ли клик в нижней части экрана (ниже 500 пикселей). Если да — вызывается captureFrame. В противном случае — запускается процесс добавления спрайтов.
Метод addSprites: заполняем экран
Метод addSprites(y) отвечает за создание одного ряда из 1024 спрайтов. Координата `y` задает вертикальную позицию ряда.
addSprites (y)
{
let color = 1;
for (let x = 0; x < 1024; x++)
{
this.add.image(x, y, `pixel${color}`).setOrigin(0);
if (color === 15)
{
color = 1;
}
}
}
В цикле для каждой позиции `xсоздается изображение (this.add.image). Ключ текстуры формируется из строкиpixelи переменнойcolor. Метод.setOrigin(0)устанавливает точку привязки спрайта в его левый верхний угол, что позволяет точно выровнять пиксели в сетку. Переменнаяcolor` циклически меняется от 1 до 15, создавая разноцветный ряд.
Наращивание нагрузки и вывод статистики
При клике в верхней части экрана (else-ветка) четыре раза подряд вызывается addSprites, что быстро увеличивает общее количество объектов на сцене.
this.addSprites(y);
y++;
total += 1024;
// ... Повторяется 4 раза
console.log('Total sprites:', total);
Каждый вызов добавляет 1024 спрайта (один ряд). Переменные `yиtotal` обновляются, чтобы отслеживать текущую позицию и общее количество. Вывод в консоль позволяет наблюдать, как растет нагрузка на рендерер.
Захват состояния экрана: captureFrame
Клик в нижней части экрана (Y >= 500) вызывает мощный метод рендерера — this.game.renderer.captureFrame(false, true).
this.game.renderer.captureFrame(false, true);
Первый аргумент (false) указывает, что захватывать нужно не весь игровой мир, а только видимую область канваса. Второй аргумент (true) включает автоматическую загрузку полученного PNG-изображения браузером. Этот инструмент незаменим для отладки визуальных артефактов или создания скриншотов во время выполнения.
Что попробовать дальше
Этот пример — отличный полигон для экспериментов. Попробуйте изменить количество создаваемых за клик спрайтов, использовать другие текстуры или отключить функцию захвата, чтобы оценить чистую производительность рендеринга. Метод captureFrame можно интегрировать в систему отчетов об ошибках, автоматически сохраняя скриншот при возникновении редкого бага.
