О чем этот пример
В Phaser для отрисовки графики чаще всего используются спрайты. Но когда требуется высокая производительность при выводе множества одинаковых объектов, на помощь приходит `Blitter` — низкоуровневый механизм отрисовки. Данный пример демонстрирует, как с помощью `Blitter` и API текстур создавать объекты напрямую из определённых кадров (`frame`) атласа, минуя создание промежуточных спрайтов. Этот подход полезен для систем частиц, тайловых карт или любых ситуаций, где нужно эффективно выводить множество статичных или редко меняющихся изображений.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.atlas('atlas', 'assets/atlas/megaset-2.png', 'assets/atlas/megaset-2.json');
}
create ()
{
const blitter = this.add.blitter(100, 200, 'atlas');
const frameAtari = this.textures.getFrame('atlas', 'atari400');
const frameBunny = this.textures.getFrame('atlas', 'bunny');
const frameCokecan = this.textures.getFrame('atlas', 'cokecan');
const frameFloppy = this.textures.getFrame('atlas', 'copy-that-floppy');
const frameHotdog = this.textures.getFrame('atlas', 'hotdog');
blitter.create(0, 0, frameAtari);
blitter.create(100, 0, frameBunny);
blitter.create(200, 0, frameCokecan);
blitter.create(300, 0, frameFloppy);
blitter.create(400, 0, frameHotdog);
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Что такое Blitter и зачем он нужен?
Blitter — это объект Phaser, предназначенный для высокопроизводительной отрисовки множества одинаковых или разных изображений. В отличие от спрайтов, Blitter работает ближе к графическому конвейеру, что снижает накладные расходы. Он идеально подходит для статичных элементов интерфейса, частиц или тайлов, которые не требуют сложной физики или анимации.
В нашем примере Blitter создаётся как контейнер, в который мы будем добавлять отдельные объекты Bob, каждый из которых представляет один кадр изображения.
Загрузка атласа и получение кадров
Перед созданием графики необходимо загрузить ресурсы. В методе preload мы используем this.load.atlas для загрузки атласа — изображения, содержащего множество отдельных картинок (кадров) и JSON-файла с их координатами.
this.load.atlas('atlas', 'assets/atlas/megaset-2.png', 'assets/atlas/megaset-2.json');
После загрузки, в create, мы получаем конкретные кадры из этого атласа с помощью метода this.textures.getFrame. Этот метод принимает ключ текстуры (имя атласа) и имя кадра внутри него, возвращая объект Frame.
const frameAtari = this.textures.getFrame('atlas', 'atari400');
const frameBunny = this.textures.getFrame('atlas', 'bunny');
// ... и так далее для других кадров
Объект Frame содержит все необходимые данные (координаты, размеры) для отрисовки конкретной части атласа.
Создание Blitter и добавление объектов Bob
Сначала мы создаём экземпляр Blitter на сцене. Конструктор принимает начальные координаты (x, y) и ключ текстуры (атласа), с которой он будет работать.
const blitter = this.add.blitter(100, 200, 'atlas');
Затем, используя метод blitter.create, мы добавляем в него объекты Bob. Каждый Bob — это отрисовываемый элемент. Метод принимает координаты (x, y) относительно позиции Blitter и объект Frame, который нужно нарисовать.
blitter.create(0, 0, frameAtari);
blitter.create(100, 0, frameBunny);
blitter.create(200, 0, frameCokecan);
// ...
Таким образом, мы размещаем пять разных изображений из одного атласа в ряд, используя один Blitter.
Конфигурация игры и запуск сцены
Как и в любом проекте Phaser, нам нужна базовая конфигурация игры. В ней мы указываем тип рендерера, элемент-контейнер, размеры холста и стартовую сцену.
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
После создания экземпляра Game Phaser автоматически запускает жизненный цикл сцены (preload, create, update). В данном примера логика полностью находится в методе create.
Что попробовать дальше
Использование Blitter вместе с прямым доступом к кадрам текстур — это мощный приём для оптимизации отрисовки в Phaser. Он позволяет минимизировать количество вызовов отрисовки и эффективно управлять множеством графических элементов.
Для экспериментов попробуйте:
1. Анимировать позиции объектов Bob, изменяя их свойства `xиyв циклеupdate`.
2. Создать сотни объектов Bob для проверки производительности в сравнении с обычными спрайтами.
3. Реализовать простую систему частиц, где новые Bob создаются в случайных позициях с определённой скоростью.
4. Использовать разные кадры из атласа для одного Blitter, создавая разнообразные композиции.
