Вот минимальный пример:
fn resolve_circle_circle_collision(circle1: &mut Circle, circle2: &mut Circle) {
let direction = circle1.pos - circle2.pos; // Вектор направления
let min_distance = circle1.radius + circle2.radius; // Минимальная дистанция (сумма радиусов)
let distance = circle1.pos.distance(circle2.pos); // Текущая дистанция между центрами
if distance < min_distance && distance > 0.0 { // Проверяем меньше ли текущая дистанция, минимальной дистанции
let overlap = min_distance - distance; // Вычисляем пересечение, решает проблему дёрганий при коллизии
let displacement = direction.normalize_or_zero() * overlap / 2.; // Вычисляем насколько двигать по направлению
circle1.pos += displacement * get_frame_time(); // Двигаем плавно т.к. используется время кадра
}
}
По сути вектор направления умноженный на время кадра, даёт необходимый эффект:
displacement * get_frame_time()
Однако если в уравнение добавить движение за мышью:
circle1.pos += direction * circle1.velocity * get_frame_time();
То всё ломается, я уже не знаю что делать с этим..
В оригинале у меня добавлен фактор интерполяции в диапазоне [0; 1] который увеличивается на N * время кадра.
И получается
displacement * factor
- это работает, но не идеально.
Видимо мои пробелы в знаниях не позволяют увидеть очевидного решения проблемы, если оно есть.
P.S: Могу записать видео, если нужно, дайте знать в комментах