2015-03-22 3 views
3

У меня возникла проблема с обнаружением столкновений с моей игрой на C++. Я сначала попробовал AABB и успешно получил его для обнаружения столкновения, но проблема заключалась в том, что я хочу быть в состоянии подталкивать друг друга, поэтому я пошел с базовым решением, чтобы подтолкнуть оба объекта к половине пройденного расстояния. Но это только подтолкнуло предметы под углом 45 градусов друг к другу. Link to GIF explaining what i meanAABB Ответ на столкновение (Push Back сталкивающиеся объекты)

ЕСЛИ ВЫ НЕ ХОТИТЕ ПРОЧИТАТЬ пропускаем этот пункт

Так что я решил, что мне нужно направление, чтобы раздвинуть объекты, поэтому я попытался изменить код из учебника. Направление - это нормализованный вектор между центром обоих объектов. И тогда половина глубины столкновения умножается на нормализованный вектор, поэтому они оказываются в противоположном направлении друг от друга. Это сработало, но оно использовало круговое столкновение (он использовал радиус + радиус для вычисления глубины столкновения), и это означало, что я не мог использовать прямоугольники с разной шириной и высотой, например 32x64 48x32 (мне пришлось использовать 32x32 48x48 64x64 и так далее так далее). Это большая проблема, потому что Мне НЕОБХОДИМО ИСПОЛЬЗОВАТЬ ТЕКСТУРЫ С РАЗЛИЧНОЙ ШИРИНЫ И ВЫСОТЫ.

Итак, снова вернулся в AABB и получил его, чтобы работать, не имея возможности подталкивать друг друга, поэтому вы просто остановитесь. Но проблема здесь в том, что когда я сталкиваюсь на одной оси, я не могу двигаться в другой. Например, если я удерживаю UP и LEFT и сталкиваюсь со стеной на LEFT, я заканчиваю полную остановку, а не продолжаю движение вверх, где нет стены.

ТАК ЧТО Я ХОЧУ ПОМОЧЬ IS либо ААББ столкновения, где объекты толкают друг друг с половиной расстояния проникали в правильном направлении или просто AABB, где вы пришли к полной остановке НО может ходить в не направление встречными при столкновении на другой оси, например Holding down up and down would result in this

+2

Интересный вопрос; но почему тег «java»? – GhostCat

+0

Если это не просто учебное упражнение, я бы рекомендовал познакомиться с Bullet (физическая библиотека). Это отлично для всех этих вещей. – Robinson

+0

@ EddyG Извините, если я неправильно использовал теги. Разве AABB не используется в играх JAVA? Возможно, я ошибаюсь. Java Tag Removed – DeeLaY

ответ

2

Вот что-то думать о ААВВ проверке столкновений:

Допустим, у вас есть два объекта ящика: O1 (х, у, ширина, высота) и O2 (x, y, ширина, высота), где «x» и «y» - нижний левый угол бо x объект.

Допустим, вы двигаетесь O1 с шагом S (х, у)

Для того, чтобы избежать полной остановки на столкновения, вы должны разделить проверку столкновений в два - один раз при столкновении для горизонтальной, и когда-то для вертикали.

Таким образом, получить различия происхождения после переезда: diff = vec2(O1.x + S.x - O2.x, O1.y + S.y - O2.y)

Прежде чем идти дальше, вы должны проверить, если два объекта не пересекаются:

if((diff.x < -O1.width || diff.x > O2.width) && (diff.y < -O1.height || diff.y > O2.height) return;

Если они не перекрываются, нет необходимости чтобы ограничить движение, и мы просто пропустим столкновение.

Тогда мы начинаем сдерживающих наше горизонтальное движение:

  1. Если diff.x меньше -O1.width, то O1 на крайнем левом. Он может свободно перемещаться по горизонтали. Итак, S.x остается как есть.

  2. Другое, если diff.x больше, чем O2.width, тогда O1 находится по правому краю и может свободно перемещаться по горизонтали. Итак, S.x остается как есть.

  3. В противном случае у нас есть ситуация, когда O1 перекрывает O2 по горизонтали. Так просто проверить if(diff.x<0) S.x -= O1.width+diff.x; и, соответственно if(diff.x>=0) S.x += O2.width-diff.x;

Ваше горизонтальное движение должно быть готово в S.x. Теперь, следуя по тому же принципу, заботиться о своем вертикальном движении:

  1. Если diff.y меньше -O1.height, то O1 намного ниже. Он может свободно перемещаться по вертикали. Итак, S.y остается как есть.

  2. Другое, если diff.y больше, чем O2.height, тогда O1 находится далеко и может свободно перемещаться по вертикали. Итак, S.y остается как есть.

  3. В противном случае у нас есть ситуация, когда O1 перекрывает O2 по вертикали. Так просто проверить if(diff.y<0) S.y -= O1.height+diff.y; и, соответственно if(diff.y>=0) S.y += O2.height-diff.y;

В сущности, в конце у вас есть S(x,y), который содержит свой новый «безопасный» движущуюся шаг. Все, что вам нужно сделать, - переместить O1 на S, а затем повторить процесс на следующем шаге.

Смежные вопросы