Cannon.js — это физический движок для JavaScript, ориентированный на реалистичное моделирование тел в 3D-пространстве. Одним из мощных инструментов для создания интерактивной игровой логики является система событий. События позволяют реагировать на изменения в физическом мире, коллизии, обновления объектов и другие действия без постоянного опроса состояния объектов в цикле.
Каждое тело (Body) и мир (World) в
Cannon.js поддерживают механизм событий через методы
addEventListener и removeEventListener.
События бывают системными (например, шаг симуляции) и
пользовательскими (например, реакция на
столкновение).
world.addEventListener('postStep', function() {
console.log('Шаг симуляции завершён');
});
Метод postStep вызывается после каждого шага симуляции.
Это позволяет обновлять логику игры синхронно с физикой.
Основное применение событий в игровых механиках — обработка
столкновений. Cannon.js предоставляет событие collide,
которое можно использовать на уровне тела:
ball.addEventListener('collide', function(event) {
const bodyB = event.body; // тело, с которым произошло столкновение
const contact = event.contact; // информация о контакте: точки, нормали, импульс
console.log('Столкновение с телом:', bodyB.id);
});
Ключевые свойства события collide:
event.body — объект типа Body,
участвующий в столкновении.
event.contact — объект ContactEquation,
содержащий:
ni — нормаль столкновения;ri, rj — точки приложения силы
относительно центров масс;impactVelocity — скорость столкновения.event.target — тело, на котором был зарегистрирован
обработчик.
Эти данные позволяют создавать реакции на столкновения, например, воспроизводить звук удара, наносить урон или изменять свойства объекта.
Помимо коллизий, World генерирует события, полезные для
глобальной игровой логики:
postStep — после каждого шага симуляции.beginContact и endContact — начало и конец
контакта между телами (реже используется напрямую, чаще через сторонние
расширения).addBody и removeBody — добавление и
удаление тел из мира.world.addEventListener('addBody', function(event) {
console.log('Новое тело добавлено в мир:', event.body.id);
});
Эти события позволяют вести учёт объектов и управлять их состоянием централизованно.
События становятся ядром игровой механики:
Пример системы триггеров:
const trigger = new CANNON.Body({ mass: 0, shape: new CANNON.Box(new CANNON.Vec3(1,1,1)) });
trigger.addEventListener('collide', function(event) {
console.log('Игрок вошёл в зону триггера!');
});
world.addBody(trigger);
Cannon.js позволяет расширять базовую модель событий, создавая
собственные триггеры. Для этого можно вручную вызывать функцию
dispatchEvent на объекте Body или
World.
playerBody.dispatchEvent({ type: 'powerUp', data: { amount: 50 } });
playerBody.addEventListener('powerUp', function(event) {
console.log('Сбор бонуса! Энергия увеличена на', event.data.amount);
});
Таким образом, физические объекты могут становиться источниками пользовательской логики, не нарушая основного цикла симуляции.
collide для всех интерактивных объектов,
требующих реакции на столкновение.postStep для обновления логики, которая
зависит от физики, но не от конкретного столкновения.0 и отключённой гравитацией, чтобы они не влияли на физику
других объектов.removeEventListener.При больших сценах с множеством динамических объектов следует:
Для визуальных движков, таких как Three.js, события Cannon.js позволяют синхронизировать модель физики с 3D-сценой:
world.addEventListener('postStep', function() {
mesh.position.copy(ball.position);
mesh.quaternion.copy(ball.quaternion);
});
Это обеспечивает точное соответствие между физическим и графическим состояниями объектов, что критично для реалистичной игровой механики.