Проблемы столкновения 2D платформера AABB

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 platformer (скопировав большую часть материала). Однако "прыжки" ошибка происходит в моей игре, в то время как это не происходит в демо AppHub. [прыгающий Жук:http://i.stack.imgur.com/NLg4j.png ]

для прыжка я проверяю, является ли игрок "onGround", затем добавьте -5 к скорости.Я.

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

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

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

3 ответов


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

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


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

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

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

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


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

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

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


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