2D Platformer AABB проблемы столкновения - PullRequest
6 голосов
/ 05 июля 2011

http://dl.dropbox.com/u/3724424/Programming/Gifs/game6.gif

У меня проблема с разрешением коллизий AABB.


Я разрешаю пересечение AABB, сначала разрешив ось X, а затем ось Y. Это сделано для предотвращения этой ошибки: http://i.stack.imgur.com/NLg4j.png


Текущий метод отлично работает, когда объект перемещается в игрока, и игрок должен толкаться горизонтально. Как видно из .gif, горизонтальные шипы толкают игрока правильно.


Однако, когда вертикальные шипы попадают в игрока, ось X все еще разрешается первой. Это делает невозможным использование шипов в качестве подъемника.

Когда игрок движется по вертикальным шипам (под действием силы тяжести, падает в них), его толкают по оси Y, потому что с начала оси X не было перекрытия.


Я попробовал метод, описанный в первом ответе по этой ссылке . Однако шипы и движущиеся объекты перемещаются, изменяя их положение, а не скорость, и я не вычисляю их следующую прогнозируемую позицию до тех пор, пока не будет вызван их метод Update (). Излишне говорить, что это решение тоже не сработало. (


Мне нужно разрешить конфликт AABB таким образом, чтобы оба описанных выше случая работали как задумано.

Это мой текущий исходный код столкновения: http://pastebin.com/MiCi3nA1

Я был бы очень признателен, если бы кто-то мог разобраться с этим, поскольку эта ошибка присутствовала в движке с самого начала, и я изо всех сил пытался найти хорошее решение, но безуспешно. Это серьезно заставляет меня проводить ночи, глядя на код столкновения, и мешает мне перейти к «забавной части» и кодированию логики игры: (


Я попытался реализовать ту же систему коллизий, что и в демонстрационной платформе XNA AppHub (скопировав большую часть материала). Однако в моей игре возникает «прыгающая» ошибка, а в демке AppHub ее нет. [прыгающая ошибка: http://i.stack.imgur.com/NLg4j.png]

Чтобы прыгнуть, я проверяю, находится ли игрок на «OnGround», затем добавляю -5 к Velocity.Y.

Поскольку Velocity.X игрока выше, чем Velocity.Y (см. Четвертую панель на диаграмме), onGround устанавливается в true, когда этого не должно быть, и, таким образом, позволяет игроку прыгать в воздухе.

Я полагаю, что этого не происходит в демоверсии AppHub, потому что Velocity.X игрока никогда не будет выше Velocity.Y, но я могу ошибаться.

Я решил эту проблему раньше, разрешив сначала по оси X, а затем по оси Y. Но это приводит к столкновению с шипами, как я уже говорил выше.

Ответы [ 3 ]

0 голосов
/ 24 августа 2013

Как уже сказал Гарет Рис, проблема заключается в том, что после обнаружения столкновения вам потребуется больше информации (как о текущем местоположении, так и о направлении, откуда оно пришло, или о последней позиции), чтобы выполнить реакцию на столкновение.

Это становится довольно сложно, если оба объекта движутся. Вместо этого выберите один объект в качестве системы отсчета и вычтите его скорость из всего остального.

Прямое решение может заключаться в создании отрезков для движения / дельты объекта без рамки отсчета. Затем пересекайте эти сегменты с 4 ребрами AABB. Это дает время пересечения и нормаль в точке пересечения. Тогда вы можете применить тот же ответ, что и сейчас.

0 голосов
/ 22 сентября 2014

Одно из возможных решений, которое я нашел, - это сортировка объектов перед разрешением по скорости игрока.

0 голосов
/ 05 июля 2011

Почему бы не разрешить ось Y сначала для вертикальных шипов, а сначала по оси X для горизонтальных шипов?

Кстати, хорошая графика.


КакЯ так понимаю, вы обрабатываете движение и столкновение примерно так:

  1. Переместите все объекты.
  2. Для каждого объекта O , проверьте на пересечение междуигрок и O , и, если необходимо, вытолкнуть игрока по горизонтали или вертикали, чтобы он больше не пересекался с O .
  3. Если игрок все еще пересекается с некоторымизатем объект (что-то) .

Это означает, что когда вы переходите к шагу (2), вы забыли, в каком направлении двигался объект O , поэтому вы не можете определить, пытается ли он подтолкнуть игрока вверх или в сторону.

Решение: на шаге (1) сохраните для каждого объекта направление, в котором он движется.Когда вы обнаружите, что игрок пересекается с объектом, вы можете посмотреть, движется ли объект вверх, вниз, влево или вправо, и это скажет вам, как выполнить выброс.

...