#c #2d #collision-detection #game-physics #collision
#c #2d #обнаружение столкновений #игра-физика #столкновение
Вопрос:
Я повсюду искал несколько советов по обнаружению столкновений, но, похоже, я действительно не могу найти ничего, что имеет смысл для меня или работает в моем случае. Я понимаю, как определить, сталкиваются ли две квадратные фигуры или нет, но я не понимаю, что делать с точки зрения правильного разделения их с помощью силы тяжести и того, что к ним не применяется.
if (tile->position.x < other->position.x Tile::size amp;amp; tile->position.x Tile::size > other->position.x amp;amp;
tile->position.y < other->position.y Tile::size amp;amp; tile->position.y Tile::size > other->position.y) {
glm::vec3 tCenter = tile->getCenter();
glm::vec3 oCenter = other->getCenter();
glm::vec3 dir = tCenter - oCenter;
dir.x = dir.x / (Tile::size / 2.0f);
dir.y = dir.y / (Tile::size / 2.0f);
tile->position = dir;
tile->velocity *= 0.0f;
}
Итак, в основном, если происходит столкновение, то раздвигайте их. Я придумал этот метод после прочтения нескольких материалов в Интернете. Это очень близко, но есть некоторые заикания, которые я, кажется, не могу понять.
Кто-нибудь знает, чего мне не хватает, или вы можете указать мне правильное направление?
Ответ №1:
Видео выглядит красиво! Это скорее предложение, но оно было слишком длинным для комментария.
За пределами этого кода нет вращения или других необычных вещей, верно? Просто гравитация, движение и некоторые границы проверяются на y = 0 (земля) или аналогично?
Кажется немного странным, что расстояние, на которое вы перемещаете каждый квадрат, пропорционально расстоянию между квадратами. Тогда квадраты, расположенные непосредственно друг над другом, даже не должны двигаться. Вы можете увидеть это в нескольких местах видео.
Вы попробуете это и дадите мне знать, если это улучшение?
Вместо этого:
dir.x = dir.x / (Tile::size / 2.0f);
dir.y = dir.y / (Tile::size / 2.0f);
tile->position = dir;
Попробуйте это:
float dmax = max(abs(dir.x), abs(dir.y));
float scaleFactor = Tile::size / dmax;
dir.x *= scaleFactor;
dir.y *= scaleFactor;
tile->position = other->position dir;
И продолжайте
tile->velocity *= 0.0f;
На самом деле я не знаю C , но я думаю, что приведенный выше код действителен. Я надеюсь, это поможет.
Комментарии:
1. Спасибо за ваше предложение. Я попробовал это, и это, казалось, работало лучше, чем другое. По-прежнему существует проблема с тем, что некоторые плитки просто скользят по другим, пока не достигнут их конца и не упадут, или их вдавливают в землю, или вдавливают в другие плитки. Должно быть, я что-то упускаю, например, не проверять одни и те же две плитки более одного раза, если это вообще имеет смысл, или что-то еще, но я понятия не имею, что может быть причиной этого.
2. или, может быть, мне нужно добавить больше итераций?
3. Я думаю, что скольжение происходит потому, что вы (предположительно) применяете силу тяжести, которая перемещает блоки немного вниз, а затем оба наших кода немного сдвигают их в сторону, чтобы увеличить расстояние между ними. Вы могли бы добавить проверку, например (если размер блока меньше 1,001 плитки ниже: не применять гравитацию). Но для этого потребуется немного больше кодирования. Меньшие временные шаги, конечно, также сделают процесс более плавным. У меня больше ничего нет в голове 🙂