В библиотеке Oimo.js обработка физических взаимодействий объектов реализуется через систему контактных колбэков. Ключевым элементом этой системы является ContactCallback, позволяющий подписываться на события столкновений между телами и реагировать на них в реальном времени.
ContactCallback представляет собой объект, который
регистрируется в мире (OIMO.World) и получает уведомления о
событиях контакта двух тел. События могут быть нескольких типов:
Эти события дают возможность отслеживать коллизии не только для физической симуляции, но и для логики игры, например, нанесения урона при столкновении, реакции на триггерные зоны или активации анимаций.
Создание колбэка требует определения объекта с методами для нужных событий. Пример базового синтаксиса:
const callback = new OIMO.ContactCallback();
callback.begin = function(contact) {
console.log('Начало контакта между', contact.body1.name, 'и', contact.body2.name);
};
callback.end = function(contact) {
console.log('Контакт завершён между', contact.body1.name, 'и', contact.body2.name);
};
callback.persist = function(contact) {
console.log('Контакт продолжается между', contact.body1.name, 'и', contact.body2.name);
};
// Регистрация в мире
world.registerContactCallback(callback);
Здесь contact — объект класса OIMO.Contact,
содержащий информацию о столкновении:
body1 и body2 – участвующие в контакте
тела.shape1 и shape2 – формы тел, участвующие в
столкновении.manifold – информация о точках контакта, нормалях и
глубине проникновения.Объект Contact предоставляет детализированную информацию для точного контроля:
contact.body1.position; // Позиция первого тела
contact.body2.velocity; // Скорость второго тела
contact.manifold.points; // Массив точек контакта
contact.manifold.normal; // Нормаль контакта
contact.manifold.depth; // Глубина проникновения
Использование этих данных позволяет реализовать:
В сложных симуляциях часто необходимо отслеживать контакты только для определённых объектов. Для этого можно использовать фильтры на основе имени тела или метки:
callback.begin = function(contact) {
if(contact.body1.name === 'Player' && contact.body2.name === 'Enemy') {
console.log('Игрок столкнулся с врагом');
}
};
Такой подход предотвращает лишние вычисления и делает обработку событий более эффективной.
Триггерные зоны Обычное применение ContactCallback — определение, когда объект входит в зону активации:
callback.begin = function(contact) {
if(contact.body1.name === 'Player' && contact.body2.name === 'Checkpoint') {
console.log('Игрок достиг контрольной точки');
}
};Урон при столкновении Используя
contact.manifold.depth и
contact.body.velocity, можно вычислять силу удара:
const impact = contact.manifold.depth * contact.body2.velocity.length();
if(impact > 5) {
console.log('Сильный удар! Нанесён урон');
}Эффекты столкновения Для визуальных эффектов можно создавать частицы или анимацию в точках контакта:
contact.manifold.points.forEach(point => {
spawnParticles(point);
});begin и
end уменьшает количество ненужных вычислений.ContactCallback тесно интегрирован с другими элементами библиотеки:
Правильное использование ContactCallback позволяет создавать сложные, реалистичные взаимодействия между объектами, сочетая физику и игровую логику.
manifold открывает возможность для кастомной
физики на уровне точек контакта, например, для симуляции мягких тел или
цепочек столкновений.Использование ContactCallback в Oimo.js обеспечивает полный контроль над событиями контакта, позволяя гибко управлять физическими взаимодействиями, реагировать на столкновения и интегрировать физику с игровой логикой.