В Cannon.js мир (World) представляет собой контейнер для
физических объектов и взаимодействий между ними. Каждый объект,
добавленный в мир, становится частью симуляции и подвергается
воздействию гравитации, столкновений и других физических сил. Для
управления телами используются методы addBody и
removeBody.
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
Здесь создается новый мир с гравитацией вдоль оси Y. После создания мира можно добавлять тела и конфигурировать их поведение.
Создание тела
Тело (Body) в Cannon.js определяется массой, формой
(Shape) и положением. Например, создание сферы:
const radius = 1;
const sphereShape = new CANNON.Sphere(radius);
const sphereBody = new CANNON.Body({
mass: 5,
position: new CANNON.Vec3(0, 10, 0),
shape: sphereShape
});
Добавление в мир
Чтобы тело начало участвовать в симуляции, его необходимо добавить в мир:
world.addBody(sphereBody);
Добавление тела делает его частью системы столкновений, и оно будет реагировать на силы и гравитацию. Важно учитывать, что порядок добавления тел может влиять на начальное поведение симуляции, особенно при сложных взаимодействиях.
Удаление тела из мира необходимо для оптимизации производительности и динамического управления сценой.
world.removeBody(sphereBody);
После удаления тело перестает участвовать в симуляции, но объект
Body остается в памяти, его можно повторно добавить в
мир.
Особенности удаления:
Constraint,
связи необходимо удалять или обновлять вручную, иначе могут возникнуть
ошибки.world.bodies
может привести к пропуску элементов, поэтому лучше удалять объекты после
завершения шага симуляции.Для работы с большим количеством тел можно использовать массивы:
const bodies = [];
for (let i = 0; i < 100; i++) {
const boxShape = new CANNON.Box(new CANNON.Vec3(1, 1, 1));
const boxBody = new CANNON.Body({ mass: 1, shape: boxShape });
boxBody.position.set(Math.random() * 10, 20, Math.random() * 10);
world.addBody(boxBody);
bodies.push(boxBody);
}
// Удаление всех тел
bodies.forEach(body => world.removeBody(body));
Преимущества такого подхода:
Иногда требуется заменить тело на другое без перезапуска симуляции:
world.removeBody(sphereBody);
const newSphere = new CANNON.Body({
mass: 10,
position: new CANNON.Vec3(0, 15, 0),
shape: new CANNON.Sphere(2)
});
world.addBody(newSphere);
Такой подход применяется для анимации разрушений, смены персонажей или динамического изменения геометрии сцены.
Добавление и удаление тел напрямую влияет на шаг симуляции:
const timeStep = 1 / 60;
function update() {
world.step(timeStep);
requestAnimationFrame(update);
}
update();
Рекомендации при динамических изменениях:
Constraint) перед удалением
тел.Каждое тело может иметь одну или несколько форм (Shape).
Добавление формы после создания тела не требует пересоздания тела, но
нужно учитывать корректное обновление инерции:
const cylinderShape = new CANNON.Cylinder(1, 1, 2, 16);
sphereBody.addShape(cylinderShape, new CANNON.Vec3(0, 2, 0));
sphereBody.updateMassProperties();
Удаление формы не предусмотрено напрямую, поэтому для замены формы чаще используют создание нового тела и замену старого в мире.
removeBody вместо деактивации.world.bodies.length после массовых операций
для отладки и предотвращения утечек памяти.Добавление и удаление тел — ключевой механизм динамической симуляции в Cannon.js, позволяющий создавать реалистичные сцены с изменяющейся физикой и оптимизировать производительность.