2D проблемы коллизии платформера с обоими осями

Я работаю над небольшой 2D игрой платформера/борьбы с C++ и SDL, и я испытываю довольно мало затруднений с обнаружением коллизий.

Уровни составлены из массива мозаик, и я использую, чтобы цикл прошел каждого (я знаю, что это не может быть лучший способ сделать это, и я могу нуждаться в помощи с этим также). Для каждой стороны символа я перемещаю его один пиксель в то направление и проверку на коллизию (я также проверяю, чтобы видеть, перемещается ли символ в то направление). Если существует коллизия, я установил скорость на 0 и перемещаю плеер в край мозаики.

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

Как я могу обработать коллизии на обеих осях, не имея тех проблем? Там какой-либо лучший путь состоит в том, чтобы обработать коллизию, чем, как я делаю его?

5
задан ausgat 17 April 2010 в 02:11
поделиться

2 ответа

В примере 2D-платформера XNA также используется коллизия на основе тайлов. То, как они справляются с этим, довольно простое и может быть полезно для вас.Вот урезанное объяснение того, что там находится (удаление специфических для их демонстрационных материалов):

  1. После применения движения он проверяет наличие коллизий.
  2. Он определяет плитки, которые игрок перекрывает, на основе ограничивающего прямоугольника игрока.
  3. Он перебирает все эти плитки ...
    1. Если проверяемый тайл не проходим:
    2. Он определяет, как далеко по осям X и Y проходит игрок перекрывает непроходимый тайл
    3. Столкновение разрешено только на мелкой оси :
      1. Если Y - пологая ось (абс (перекрытие. y)
      2. Ограничивающая рамка обновляется в зависимости от изменения позиции
    4. Перейти к следующей плитке ...

Она находится в player.cs в функции HandleCollisions (), если вы берете код и хотите увидеть, что они конкретно там делать.

4
ответ дан 15 December 2019 в 00:55
поделиться

Да. Столкновения на основе векторов будут намного лучше, чем на основе плиток. Определите каждый край плитки как линии (есть короткие отрезки, но пока не обращайте на них внимания). Теперь, чтобы увидеть, произошло ли столкновение, найдите ближайшие горизонтальную и вертикальную линии. если вы возьмете знак lastPos.x * LineVector.y - lastPos.y * LineVector.x и сравните его с thisTurnsPos.x * LineVector.y - ThisTurnsPos.y * LinePos.x. Если знаки этих двух значений различаются, значит, вы пересекли эту черту. Это не проверяет, пересекли ли вы конец отрезка линии.Вы можете сформировать точечный продукт между тем же lineVector и вашим curPosition (небольшая ошибка здесь, но, вероятно, достаточно хорошая), и он либо отрицателен, либо больше квадрата величины линии, вы не находитесь в этом сегменте линии, и столкновения не произошло .

Это очень сложно, и вам, вероятно, удастся обойтись простой проверкой сетки, чтобы увидеть, не перешли ли вы в область другого квадрата. Но! Преимущество выполнения этого с векторами заключается в том, что он решает перемещение быстрее, чем размер проблемы с блоком столкновений, и (что более важно) вы можете использовать линии, не выровненные по оси для ваших столкновений. Эта система работает с любыми 2D-векторами (а также с 3D-изображениями, немного массируя). Она также позволяет вам довольно легко перемещать вашего персонажа по краю поля столкновения, потому что вы уже выполнили 99% математических расчетов, необходимых для найти, где вы должны быть после столкновения.

Я замалчил пару деталей реализации, но могу сказать, что использовал вышеупомянутый метод в бесчисленных коммерческих видеоиграх, и он отлично сработал. Удачи!

0
ответ дан 15 December 2019 в 00:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: