О чем этот пример
При создании игр с обширными уровнями или большим количеством спрайтов критически важна оптимизация производительности. Класс `Blitter` в Phaser 3 — это мощный инструмент для отрисовки тысяч спрайтов с минимальными затратами ресурсов, так как он использует один текстуру-атлас и метод пакетной отрисовки (batch rendering). В этой статье мы разберем, как создавать сетки из сотен объектов с помощью `Blitter` и реализовать плавное управление камерой с помощью встроенного контроллера `SmoothedKeyControl`. Этот подход идеально подходит для прототипирования карт, изометрических миров или сцен с большим количеством частиц.
Версия 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.spritesheet('bobs', 'assets/sprites/bobs-by-cleathley.png', { frameWidth: 32, frameHeight: 32 });
}
create ()
{
const blitter = this.add.blitter(0, 0, 'bobs');
// Create a load of bobs aligned in a grid
for (let y = 0; y < 30; y++)
{
for (let x = 0; x < 30; x++)
{
blitter.create(x * 32, y * 32, Phaser.Math.Between(0, 399));
}
}
const cursors = this.input.keyboard.createCursorKeys();
const controlConfig = {
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
up: cursors.up,
down: cursors.down,
zoomIn: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q),
zoomOut: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E),
acceleration: 0.06,
drag: 0.0005,
maxSpeed: 1.0
};
this.controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
}
update (time, delta)
{
this.controls.update(delta);
}
}
const config = {
type: Phaser.CANVAS,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Оптимизация через Blitter
Основная задача Blitter — эффективное отображение множества спрайтов из одного набора кадров (spritesheet). Вместо создания сотен отдельных игровых объектов (Sprite), которые нагружают систему, Blitter работает как конвейер, рисуя множество копий (бобов) из одного источника.
В методе preload загружается спрайтшит, содержащий 400 отдельных кадров (по 32x32 пикселя).
this.load.spritesheet('bobs', 'assets/sprites/bobs-by-cleathley.png', { frameWidth: 32, frameHeight: 32 });
В create создается один объект Blitter, который будет отвечать за отрисовку всех элементов.
const blitter = this.add.blitter(0, 0, 'bobs');
Создание сетки объектов
Для заполнения сцены используется двойной цикл, который создает 30x30 (900) бобов, располагая их в сетку. Ключевой метод — blitter.create(x, y, frame).
* **x, y**: Координаты для отрисовки данного боба на экране.
* **frame**: Индекс кадра из загруженного спрайтшита. Phaser.Math.Between(0, 399) случайным образом выбирает один из 400 доступных кадров для каждого боба, создавая визуальное разнообразие.
for (let y = 0; y < 30; y++) {
for (let x = 0; x < 30; x++) {
blitter.create(x * 32, y * 32, Phaser.Math.Between(0, 399));
}
}
В результате мы получаем поле размером 960x960 пикселей, состоящее из 900 спрайтов, но с высокой производительностью.
Настройка плавного управления камерой
Чтобы исследовать созданный большой мир, нужна камера, которой можно управлять. Phaser предоставляет готовый контроллер SmoothedKeyControl для реализации плавного, инерционного движения камеры с клавиатуры.
Сначала создаются объекты для отслеживания нажатий стрелок.
const cursors = this.input.keyboard.createCursorKeys();
Затем настраивается конфигурационный объект для контроллера. В нем указывается камера (this.cameras.main), привязка клавиш для движения и зума, а также параметры физики движения: ускорение, сопротивление (drag) и максимальная скорость.
const controlConfig = {
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
up: cursors.up,
down: cursors.down,
zoomIn: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q),
zoomOut: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E),
acceleration: 0.06,
drag: 0.0005,
maxSpeed: 1.0
};
this.controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
Обновление состояния контроллера
Контроллер SmoothedKeyControl не обновляется автоматически. Необходимо вручную вызывать его метод update в каждом кадре игрового цикла, передавая дельту времени (delta). Это позволяет контроллеру корректно рассчитать плавное движение и инерцию, независимо от частоты кадров.
update (time, delta) {
this.controls.update(delta);
}
Без этого вызова камера не будет реагировать на нажатия клавиш.
Что попробовать дальше
Комбинация Blitter для эффективного рендеринга и SmoothedKeyControl для навигации — это мощный дуэт для создания прототипов больших игровых миров в Phaser 3. Вы получаете основу для тайловых карт, систем частиц или стратегий с видом сверху без падения производительности.
Для экспериментов попробуйте: изменить логику создания бобов на лету в ответ на клики мыши; использовать другой контроллер, например, FixedKeyControl, для мгновенного перемещения камеры; или привязать зум камеры к колесику мыши, переопределив методы обработки ввода.
