Библиотека Cannon.js предоставляет мощный движок физики для JavaScript с поддержкой жестких тел, столкновений и динамики. Важным элементом работы является объект World, который управляет симуляцией и хранит все тела сцены. Одной из ключевых возможностей является использование встроенных событий, позволяющих реагировать на изменения мира и управлять телами динамически.
postStepСобытие postStep вызывается после
каждого шага симуляции мира. Этот механизм обеспечивает выполнение кода
после того, как все физические расчеты текущего кадра
завершены.
Синтаксис:
world.addEventListener('postStep', function(event) {
// Код, выполняющийся после шага симуляции
});
Особенности:
Пример применения:
const world = new CANNON.World();
world.broadphase = new CANNON.NaiveBroadphase();
world.gravity.set(0, -9.82, 0);
world.addEventListener('postStep', () => {
world.bodies.forEach(body => {
if (body.position.y < 0) {
body.position.y = 5; // возвращаем тело на стартовую высоту
}
});
});
const sphereBody = new CANNON.Body({
mass: 1,
shape: new CANNON.Sphere(1)
});
world.addBody(sphereBody);
function simulate() {
world.step(1/60);
requestAnimationFrame(simulate);
}
simulate();
В этом примере каждое тело, упавшее ниже уровня y=0,
возвращается на высоту 5 единиц после завершения шага физики.
addBodyСобытие addBody срабатывает при
добавлении тела в мир. Оно полезно для логирования, динамического
изменения свойств или запуска связанных процессов при добавлении новых
объектов.
Синтаксис:
world.addEventListener('addBody', function(event) {
const body = event.body;
// Действия с добавленным телом
});
Особенности:
event.body содержит ссылку на добавляемое тело.Пример использования:
world.addEventListener('addBody', (event) => {
console.log(`Тело добавлено: масса = ${event.body.mass}`);
if (event.body.mass > 10) {
event.body.linearDamping = 0.9; // уменьшение скорости для тяжелых тел
}
});
const boxBody = new CANNON.Body({
mass: 12,
shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1))
});
world.addBody(boxBody);
Здесь при добавлении коробки автоматически устанавливается демпфирование, если масса превышает пороговое значение.
removeBodyСобытие removeBody срабатывает при
удалении тела из мира. Это позволяет корректно управлять ресурсами и
реализовать дополнительные действия при удалении объектов.
Синтаксис:
world.addEventListener('removeBody', function(event) {
const body = event.body;
// Очистка ресурсов или обновление логики
});
Особенности:
event.body возвращает удаляемое тело.Пример применения:
world.addEventListener('removeBody', (event) => {
console.log(`Тело удалено: ${event.body.id}`);
if (event.body.userData) {
// Очистка пользовательских данных
delete event.body.userData;
}
});
world.removeBody(boxBody);
В этом примере при удалении тела автоматически выполняется очистка пользовательских данных, связанных с объектом.
Комбинирование событий Часто удобно сочетать
addBody и removeBody с postStep,
чтобы отслеживать динамическую симуляцию и управлять объектами по мере
их появления и исчезновения.
Избегать тяжелых вычислений в
postStep Поскольку это событие вызывается каждый
кадр, интенсивные операции могут замедлить симуляцию. Логичнее делать
обновления только для необходимых тел.
Использование пользовательских данных
(userData) Каждое тело можно расширять
произвольными данными для управления логикой внутри событий. Это
особенно полезно при массовой симуляции объектов.
Обеспечение согласованности Изменения тел внутри
postStep происходят после завершения всех столкновений и
интеграции. Это безопасный момент для корректировки позиции, скорости
или удаления тела без риска нарушить расчет столкновений текущего
кадра.
Эти события формируют основу для интерактивной и динамичной симуляции в Cannon.js, позволяя полностью контролировать создание, изменение и удаление объектов в мире, а также реагировать на каждый шаг физики с высокой точностью.