О чем этот пример
При создании игр с большим количеством статичных или редко меняющихся спрайтов (частицы, элементы фона, тайлы) классические `Sprite` объекты могут стать узким местом производительности. Каждый такой объект несет накладные расходы на управление физикой, анимацией и событиями. Пример 'Single Image Bob' демонстрирует альтернативный, высокопроизводительный подход с использованием `Blitter` и `Bob`. Это система отрисовки, которая работает с 'штампованными' изображениями (`Bob`) на канвасе, минимизируя вызовы отрисовки. Она идеальна для случаев, когда вам нужна максимальная скорость отрисовки множества копий одного изображения без лишних функциональных наворотов.
Версия 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('atari', 'assets/sprites/atari130xe.png');
}
create ()
{
const blitter = this.add.blitter(0, 0, 'atari');
const bob = blitter.create(100, 100);
console.log(blitter.children);
console.log(blitter.getRenderList());
}
}
const config = {
type: Phaser.CANVAS,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое Blitter и Bob?
Blitter — это специальный игровой объект (Phaser.GameObjects.Blitter), который служит контейнером и менеджером для объектов Bob. Его можно представить как доску для штамповки.
Bob (Phaser.GameObjects.Bob) — это легковесный объект, представляющий одну отрисовку (один «штамп») текстуры в определенной позиции на экране. Bob не является Sprite — у него нет тела для физики, компонентов для анимации или встроенных методов для обработки ввода. Это просто данные для отрисовки: позиция (x, y), кадр текстуры и флаги видимости.
Их основная сила — в объединенной пакетной отрисовке. Все Bob, принадлежащие одному Blitter, рисуются за один вызов отрисовщика (рендер-колл), что критически важно для производительности при работе с тысячами объектов.
Разбор примера: от загрузки до создания
Давайте пройдемся по коду примера шаг за шагом.
В методе preload загружается одно-единственное изображение, которое будет использоваться как источник для всех создаваемых Bob. Важно понимать, что Blitter работает с одной текстурой (или атласом) за раз.
this.load.image('atari', 'assets/sprites/atari130xe.png');
В методе create происходит магия. Сначала создается сам объект Blitter. Его координаты (0, 0) задают начало системы координат для всех его дочерних Bob.
const blitter = this.add.blitter(0, 0, 'atari');
Затем с помощью метода blitter.create(x, y) создается один объект Bob. Аргументы `xиyзадают его позицию относительно родительскогоBlitter. В данном случае спрайтatari` появится на экране в координатах (100, 100).
const bob = blitter.create(100, 100);
Управление Bob и внутренняя структура Blitter
Созданный Bob автоматически добавляется во внутренние списки Blitter. Пример выводит в консоль два важных свойства, которые помогают понять внутреннее устройство.
blitter.children — это массив всех созданных объектов Bob. Вы можете перебирать его в цикле, чтобы массово изменять их свойства, например, позиции для создания волнового эффекта.
console.log(blitter.children);
blitter.getRenderList() — это оптимизированный массив Bob, которые *фактически* будут отрисованы в текущем кадре. Если Bob невидим (bob.visible = false), он будет исключен из этого списка, что еще больше ускоряет рендеринг.
console.log(blitter.getRenderList());
Каждый Bob имеет простейшие свойства для управления:
bob.x = 200; // Изменить позицию по X
bob.y = 150; // Изменить позицию по Y
bob.visible = false; // Скрыть этот Bob
bob.frame = frameObject; // Изменить отображаемый кадр текстуры (если используется атлас)
Ключевые отличия от обычных Sprite
1. **Производительность:** Один Blitter с тысячей Bob выполнит один вызов отрисовки. Тысяча отдельных Sprite — тысячу вызовов.
2. **Функциональность:** У Bob нет тела для this.physics.add.image, нет анимаций, нет обработчиков событий мыши/касания. Это «тупые» пиксели.
3. **Управление:** Bob управляются через родительский Blitter или напрямую через ссылку. Для их перемещения вы просто меняете свойства `xиy`, а движок сам позаботится об эффективной отрисовке.
4. **Память:** Bob использует меньше памяти, чем полноценный Sprite.
Используйте Blitter, когда вам нужно много статичных или простейших объектов (звездный фон, пыль, трава, пули в классическом шутере). Используйте Sprite, когда объекту нужна физика, сложная анимация или интерактивность.
Практические паттерны использования
**Создание частиц для взрыва:**
createExplosion(x, y) {
const particles = this.add.blitter(x, y, 'particle');
for (let i = 0; i < 50; i++) {
const bob = particles.create(0, 0);
bob.x = Phaser.Math.Between(-20, 20);
bob.y = Phaser.Math.Between(-20, 20);
// Установка таймера на скрытие Bob через 300мс
this.time.delayedCall(300, () => { bob.visible = false; });
}
}
**Массовое обновление (параллакс-фон):**
// В update()
this.blitterStars.children.forEach((bob, index) => {
// Медленно двигаем каждый Bob влево с разной скоростью
bob.x -= (index % 3 + 1) * 0.1;
if (bob.x < -100) bob.x = 800; // Возвращаем на правый край экрана
});
**Использование атласов:** Вы можете создавать Bob с разными кадрами из одной текстуры, что полезно для тайловых карт или наборов иконок.
const blitter = this.add.blitter(0, 0, 'tileset');
const frame = this.textures.getFrame('tileset', 'grass');
const bob = blitter.create(64, 128);
// Устанавливаем конкретный кадр текстуры
bob.frame = frame;
Что попробовать дальше
Blitter — это мощный инструмент оптимизации для специфичных задач в Phaser. Он позволяет достичь высокой частоты кадров в сценах с огромным количеством визуальных объектов, жертвуя их функциональной сложностью.
**Идеи для экспериментов:**
1. Создайте систему звездного поля с 5000 Bob, где каждая звезда движется с уникальной скоростью для эффекта параллакса.
2. Реализуйте простейшую систему частиц для выхлопа корабля, создавая и переиспользуя Bob из пула.
3. Сравните FPS в сцене с 2000 Bob и 2000 Sprite при их одновременном движении.
4. Используйте Blitter для отрисовки статичного тайлового фона большой карты, генерируя Bob только для видимой области.
