Culling в контексте игровых движков означает процесс определения и исключения объектов, которые не видимы на экране, чтобы оптимизировать производительность. В Phaser culling используется для экономии ресурсов при рендеринге сцены с большим количеством спрайтов или тайлсетов.
Phaser предоставляет два основных подхода к culling: автоматический и ручной. Каждый из них имеет свои особенности и области применения.
Phaser использует систему камер для определения, какие объекты находятся в видимой области. Спрайты, текстуры и тайлы проверяются на пересечение с областью камеры, и рендерятся только те, что видны.
Ключевые моменты:
TilemapLayer и Group.Group используется проверка метода
Camera.worldView, который возвращает область видимости
камеры.Пример автоматического culling для TilemapLayer:
const map = this.make.tilemap({ key: 'level1' });
const tileset = map.addTilesetImage('tiles', 'tilesImage');
const layer = map.createLayer('Ground', tileset, 0, 0);
// Включение автоматического culling
layer.setCullPadding(32); // добавляет запас пикселей, чтобы тайлы появлялись заранее
Особенности:
setCullPadding(pixels) позволяет заранее рендерить
тайлы за пределами экрана, чтобы избежать внезапного появления
объектов.Ручное culling требуется, когда нужно больше контроля над процессом рендеринга объектов. Например, когда объекты частично видны, а их рендеринг должен зависеть от сложной логики.
Подходы к ручному culling:
function isVisible(sprite, camera) {
const bounds = sprite.getBounds();
return Phaser.Geom.Intersects.RectangleToRectangle(bounds, camera.worldView);
}
sprites.forEach(sprite => {
sprite.visible = isVisible(sprite, this.cameras.main);
});
Group с объектами, которые подлежат
culling.update цикле.sprite.setVisible(true|false) вместо удаления объекта.Преимущества ручного подхода:
Оптимизация тайлсетов:
TilemapLayer.setCullPadding, чтобы тайлы подгружались
заранее.Оптимизация спрайтов и групп:
setActive и setVisible
вместо удаления из сцены.Пример комбинированного подхода:
const enemies = this.add.group();
enemies.getChildren().forEach(enemy => {
enemy.setActive(false);
enemy.setVisible(false);
});
function update() {
enemies.getChildren().forEach(enemy => {
const visible = Phaser.Geom.Intersects.RectangleToRectangle(
enemy.getBounds(), this.cameras.main.worldView
);
enemy.setActive(visible);
enemy.setVisible(visible);
});
}
Такой подход сочетает автоматическое определение области камеры и ручное управление активностью объектов, что позволяет добиться максимальной производительности на больших уровнях.
body.enable = false.sprite.anims.pause()), чтобы не тратить ресурсы на
проигрывание анимаций вне экрана.Эффективное использование culling в Phaser позволяет уменьшить количество рендеримых объектов, снизить нагрузку на GPU и CPU, повысить FPS и обеспечить плавное воспроизведение сцены даже на слабых устройствах.