О чем этот пример
При создании игр с большим количеством одинаковых объектов, например, частиц или тайлов, производительность может стать проблемой. Phaser предоставляет мощный инструмент `Blitter`, который позволяет отрисовывать множество экземпляров одного изображения (или его частей) с минимальными накладными расходами. В этой статье мы разберем базовый пример его использования, чтобы вы могли сразу применять этот метод для оптимизации своих проектов, создавая стаи врагов, массивы звезд или поля травы без ущерба для скорости отрисовки.
Версия 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');
blitter.create(0, 0);
blitter.create(200, 50);
blitter.create(400, 100);
blitter.create(600, 150);
}
}
const config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое Blitter?
Blitter (от "bit blit" — операция быстрого копирования блоков битов) — это специальный игровой объект в Phaser, предназначенный для высокопроизводительного отображения множества спрайтов из одного источника текстуры. В отличие от создания отдельных объектов Image или Sprite, Blitter управляет так называемыми Bob-объектами, которые являются легковесными ссылками на область основного изображения. Это кардинально снижает нагрузку на графический процессор при рендеринге идентичных или частично совпадающих спрайтов.
В нашем примере мы создадим один Blitter, использующий текстуру 'atari', а затем разместим четыре его копии (Bob) в разных позициях на сцене.
Подготовка ассета
Первым шагом необходимо загрузить изображение, которое будет служить источником для всех создаваемых Bob-объектов. Это делается в методе preload() сцены. Важно задать правильный базовый URL или путь к файлу.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('atari', 'assets/sprites/atari130xe.png');
}
Здесь this.load.setBaseURL() устанавливает корневую папку для загрузки, а this.load.image() загружает текстуру с ключом 'atari' из указанного URL.
Создание Blitter и размещение Bob
Основная магия происходит в методе create(). Сначала мы создаем сам объект Blitter, указывая его начальную позицию (0, 0) и ключ текстуры.
const blitter = this.add.blitter(0, 0, 'atari');
После этого мы можем создавать отдельные Bob-объекты, которые будут отрисовывать текстуру 'atari'. Для этого используется метод .create(x, y) объекта blitter. Каждый вызов этого метода создает новый Bob в указанных координатах относительно всего Blitter. Координаты самого Blitter (0,0 в нашем случае) служат точкой отсчета.
blitter.create(0, 0);
blitter.create(200, 50);
blitter.create(400, 100);
blitter.create(600, 150);
В результате на сцене появятся четыре спрайта Atari, расположенных по диагонали. Все они используют одну и ту же текстуру в памяти видеокарты.
Конфигурация игры
Для запуска примера необходима стандартная конфигурация игры Phaser. В этом примере используется WEBGL-рендерер, который необходим для работы Blitter.
const config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Обратите внимание на параметр type: Phaser.WEBGL. Blitter работает только с WebGL-рендерером и не будет функционировать в режиме Canvas.
Что попробовать дальше
Blitter — это фундаментальный инструмент Phaser для оптимизации отрисовки множества одинаковых объектов. Как мы увидели, его использование сводится к созданию одного контейнера и генерации в нем легковесных Bob-объектов. Для экспериментов попробуйте создать сотни Bob в цикле, анимировать их положение, изменять им свойства (например, frame или tint), или использовать Blitter для создания системы частиц. Это отличный старт для понимания принципов эффективного рендеринга в ваших играх.
