Как мне справиться с обнаружением столкновений, чтобы быстрые объекты не проходили сквозь стены?

14

Я создаю 2D-шутер с боковой прокруткой, и у меня возникли небольшие проблемы с обнаружением столкновения для пуль. Все, включая маркеры, являются объектами со своими собственными полигонами / методами обновления.

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

Что я могу сделать по этому поводу? Единственное, что мне удалось придумать, - это нарисовать линию из старой позиции в новую и выполнить обнаружение столкновения, но рисование линий для обнаружения столкновения рекомендуется в документации slick2d. Как я могу решить это?

скуловая кость
источник
Не полный ответ, поэтому комментарий. Я бы никогда не рекомендовал графически рисовать линию, но математически вы можете сделать это, просто пересечение плоскости луча, чтобы увидеть, произошло ли столкновение. Затем вы можете выполнить обнаружение с меньшим фиксированным шагом, чтобы получить точный момент (и всю информацию, которая приходит вместе с ним), когда произошло столкновение без необходимости работать с постоянно более высокой скоростью, как это предлагается в ответах. Проведите менее дорогостоящую проверку, а затем потратьте время на получение точного ответа, который вам необходим.
Джеймс

Ответы:

9

Стандартные подходы (выбрать один):

  1. Увеличьте ширину вашей границы И / ИЛИ уменьшите максимальную скорость вашей пули, чтобы она никогда не могла прыгнуть через стену в одном обновлении (требует немного Пифагора, чтобы выяснить максимальные расстояния / минимальную ширину границы);
  2. Выполните непрерывное обнаружение столкновений (CCD), обычно с помощью лучевого вещания, чтобы обнаружить столкновение с линейными (2) или плоскими (3D) поверхностями впереди движущегося объекта. Это дороже, но является более всесторонним решением. Raycasting против 2D линий довольно прост, но в этом случае вам нужно определить все ваши границы как прямые полигоны.

Впрочем, вместо этого вы можете смоделировать ваши пули как лучи - если это соответствует внешнему виду вашей игры, как в left4kdead . Таким образом, вам не нужно приближать пули к лучам, потому что они уже являются лучами. С точки зрения внешнего вида, это может выглядеть прилично, если вы рисуете линию с более ярким пятном на конце пули, или просто рисуете линию как градиент от светлого (конец пули) к темному (хвостовой конец), создавая видимость движение.

Я бы согласился с тем, что в большинстве случаев использование графики для обнаружения столкновений немного ошибочно, однако идеальное обнаружение столкновений с точностью до пикселя - именно это и является принятой техникой. Я думаю, все зависит от того, чего вы хотите достичь и как быстро. Если вам не нужна очень быстрая игра с множеством тел + действий, сделайте это. Еще лучше использовать один из подходов, которые я изложил выше.

инженер
источник
Спасибо за отличный ответ - в идеале я бы хотел, чтобы он быстро развивался со многими движущимися телами. Причина, по которой я воспринимаю пули как физические объекты, заключается в том, что на них влияет гравитация, как и на все остальное (поэтому слегка изгибаюсь, в зависимости от скорости пули и т. Д.). Разве это не хороший способ сделать это? Это моя первая игра, поэтому я все еще ищу лучшие практики. Я мог бы также использовать параболическое уравнение, но я не уверен, как бы я установил коэффициенты, относящиеся к углу скорости / цели пули
Мала
3
Это звучит как слишком много деталей для пуль. В реальной жизни, когда вы стреляете пулей, вы вряд ли когда-либо обнаружите этот слизень из-за силы рикошета, непредсказуемости угла рикошета и т. Д. Или же он просто входит в тело и остается там (дерево, человек). Я просто хотел бы, чтобы они исчезли или рикошет, а затем исчезли вскоре после этого. Сосредоточьтесь на своем основном игровом процессе, не беспокойтесь об этих мелких деталях. Реализм лучше всего сосредоточен на вещах, которые имеют значение.
инженер
Да, я полагаю, я могу просто использовать прямые линии для пуль и, возможно, найти способ заставить их изогнуться немного позже, если это кажется важным.
Мала
2
Если скорость пуль не слишком высока (т. Е. Не так высока, что вы не сможете увидеть, как они движутся по экрану), тогда вы можете просто применить гравитацию к их скорости, продолжая моделировать обнаружение столкновений с помощью простых лучей. Пользователь не будет замечать, что пуля движется как серия прямых линий, больше, чем он заметит, как все ваши другие объекты делают то же самое. Для следов пули вычисление и рисование изогнутого следа (сплайна) не сложно и увеличит иллюзию плавного изгиба траектории пули.
Шон Мидлдич
3

Если вы хотите, чтобы ваши пули вели себя как реалистичные физические объекты (например, ваши пули больше похожи на стрелы или камни из катапульты, чем на пушечный выстрел), то вы также можете попытаться увеличить частоту обновлений своей физики.

Таким образом, хотя ваша игра может работать со скоростью 60 кадров в секунду, физическая симуляция может работать со скоростью 120 обновлений в секунду (вот повсеместная статья об исправлении временного шага, в которой объясняется хорошая настройка физики, которая может работать с другой скоростью, чем цикл рендеринга).

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

bummzack
источник
Благодарность! Я эффективно делаю это (а также использую линейные снаряды) и надеюсь, что это останется выполнимым, так как игра усложняется
Мала