Cannon.js предоставляет мощный механизм для контроля взаимодействий объектов через collision groups и collision masks. Эти инструменты позволяют задавать, какие объекты должны сталкиваться, а какие — игнорироваться, что особенно важно при работе с большими сценами или сложными физическими симуляциями.
В Cannon.js каждый Body может быть назначен в одну или несколько групп и иметь маску столкновений. Эти параметры определяют поведение тела при проверке столкновений с другими объектами.
Collision group — это числовой битовый флаг, который определяет принадлежность тела к определенной группе столкновений.
const body = new CANNON.Body({
mass: 1,
shape: new CANNON.Sphere(1)
});
body.collisionFilterGroup = 1; // Присваиваем тело к группе 1
|).Пример с объединением групп:
body.collisionFilterGroup = 1 | 2; // Тело принадлежит одновременно к группам 1 и 2
Collision mask определяет, с какими группами объектов тело может сталкиваться.
body.collisionFilterMask = 1; // Тело будет сталкиваться только с объектами из группы 1
collisionFilterGroup одного тела с
collisionFilterMask другого и наоборот. Если результат не
равен нулю, столкновение происходит.Пример проверки:
bodyA.collisionFilterGroup & bodyB.collisionFilterMask !== 0 &&
bodyB.collisionFilterGroup & bodyA.collisionFilterMask !== 0
Если выражение истинно, объекты могут взаимодействовать.
Изоляция определенных объектов Игровые объекты, которые не должны сталкиваться между собой (например, пули одного игрока), можно поместить в отдельную группу и настроить маску так, чтобы они взаимодействовали только с окружением.
const playerBullets = new CANNON.Body({ mass: 1, shape: new CANNON.Sphere(0.1) });
playerBullets.collisionFilterGroup = 2;
playerBullets.collisionFilterMask = 1; // Только с окружениемСоздание сложной сцены с множеством групп В симуляции с NPC, игроком, стенами и динамическими объектами можно распределить группы:
Тогда маски можно задать так, чтобы пули сталкивались только со стенами и NPC, игрок мог столкнуться с NPC и стенами, а NPC — только с игроком и стенами.
player.collisionFilterGroup = 2;
player.collisionFilterMask = 1 | 4; // Столкновение со стенами и NPC
npc.collisionFilterGroup = 4;
npc.collisionFilterMask = 1 | 2; // Столкновение со стенами и игроком
bullet.collisionFilterGroup = 8;
bullet.collisionFilterMask = 1 | 4; // Столкновение со стенами и NPCОптимизация производительности Ограничение лишних проверок столкновений снижает нагрузку на физический движок. В больших сценах использование масок особенно эффективно, когда сотни объектов перемещаются одновременно.
Пример:
const WALL = 1; // 0001
const PLAYER = 2; // 0010
const ENEMY = 4; // 0100
collisionFilterGroup = PLAYER и
collisionFilterMask = WALL | ENEMY (0010 & 0001, 0010
& 0100) столкнется с объектами WALL и ENEMY.collisionFilterGroup = ENEMY и
collisionFilterMask = WALL столкнется только со
стенами.Использование collision groups и collision masks обеспечивает гибкое управление взаимодействиями объектов, снижает вычислительные затраты и позволяет создавать сложные симуляции без конфликтов между объектами.