Библиотека Cannon.js предоставляет мощный физический движок для
симуляции трёхмерной механики тел в JavaScript. В основе работы лежит
World — пространство, в котором происходят все
взаимодействия. Объект CANNON.World создаётся следующим
образом:
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0); // стандартная гравитация
world.broadphase = new CANNON.NaiveBroadphase(); // упрощённая проверка столкновений
world.solver.iterations = 10; // точность решения контактов
Ключевые моменты:
gravity определяет направление и величину силы
тяжести.broadphase отвечает за алгоритм определения
потенциальных столкновений между телами.solver.iterations влияет на стабильность симуляции при
большом числе контактов.Создание новых тел каждый кадр может быть ресурсоёмким, особенно при динамических сценах с большим количеством объектов. Для оптимизации используется пулинг — повторное использование заранее созданных объектов. В Cannon.js пулинг реализуется вручную через массивы.
Пример структуры пулинга:
class BodyPool {
constructor(shape, mass, size) {
this.pool = [];
this.shape = shape;
this.mass = mass;
this.size = size || 50;
for (let i = 0; i < this.size; i++) {
const body = new CANNON.Body({ mass: this.mass });
body.addShape(this.shape);
body.position.set(0, -100, 0); // прячем объект вне видимой сцены
this.pool.push(body);
}
}
acquire() {
return this.pool.length ? this.pool.pop() : null;
}
release(body) {
body.velocity.set(0, 0, 0);
body.angularVelocity.set(0, 0, 0);
body.position.set(0, -100, 0);
body.quaternion.set(0, 0, 0, 1);
this.pool.push(body);
}
}
Важные детали:
Cannon.js использует примитивные формы для расчёта столкновений. Основные типы:
Box: прямоугольный параллелепипед
const boxShape = new CANNON.Box(new CANNON.Vec3(1, 1, 1));Sphere: сфера
const sphereShape = new CANNON.Sphere(0.5);Cylinder: цилиндр
const cylinderShape = new CANNON.Cylinder(0.5, 0.5, 2, 16);Plane: бесконечная плоскость для пола
const groundShape = new CANNON.Plane();Каждое тело (CANNON.Body) может содержать одну или
несколько форм, что позволяет создавать сложные составные объекты.
После создания пулинга тела необходимо добавить в мир для взаимодействия:
const spherePool = new BodyPool(new CANNON.Sphere(0.5), 1, 100);
for (let i = 0; i < 50; i++) {
const sphere = spherePool.acquire();
if (sphere) {
sphere.position.set(Math.random()*5, 10 + i, Math.random()*5);
world.addBody(sphere);
}
}
Особенности:
Чтобы объекты не накапливались в мире и не замедляли симуляцию, их возвращают в пул:
function update() {
world.step(1/60);
world.bodies.forEach(body => {
if (body.position.y < -10) { // объект упал ниже границы
world.removeBody(body);
spherePool.release(body);
}
});
}
Ключевые моменты:
world.bodies, чтобы не перегружать расчёт
столкновений.Использование пулинга в Cannon.js позволяет создавать высокопроизводительные симуляции с большим количеством объектов. Правильное управление состоянием тел, оптимизация пула и внимательное использование форм обеспечивают стабильную и реалистичную физику даже в сложных сценах.