Android обнаружения столкновений (с астероидами!!)

В настоящее время я создаю java-игру для Android. Этакая игра типа лунного посадочного модуля. Я хочу реализовать какие-то препятствия и выбрал астероиды, которые будут случайным образом размещаться на экране.

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

Я предполагаю, что мне нужно использовать какие-то ограничивающие круги, но не совсем уверен, как я могу настроить это с изображениями?

Думаю, если бы все астероиды были одинакового размера, я мог бы жестко закодировать некоторые точки для круглой/многоугольной ограничивающей рамки, а затем преобразовать их в положение изображений — так что, по сути, многоугольник — это форма астероида?

Любые предложения о наилучшем способе сделать это были бы замечательными. Кроме того, если бы кто-то мог придумать какой-нибудь высокоуровневый псевдокод обнаружения столкновений, это было бы признательно :)


person Dave Clarke    schedule 02.03.2013    source источник
comment
В чем проблема с круглыми формами? Вы можете сделать что-то такое же простое, как collision = distance(c1.center,c2.center) < c1.radius+c2.radius.   -  person A. Rodas    schedule 03.03.2013
comment
Посадочный модуль имеет прямоугольную форму, а астероиды круглые — извините, что не сделал это яснее.   -  person Dave Clarke    schedule 03.03.2013


Ответы (1)


Если прямоугольник посадочного модуля выровнен по оси (его края параллельны осям координат), легко проверить коллизии с кругами. Дан круг с радиусом r и центром (cx, cy) и прямоугольник с началом координат (x, y), шириной w и высотой h; они сталкиваются, если верно одно из следующих условий:

  • (x < cx < x+w) и (y-r < cy < y+h+r)
  • (y < cy < y+h) и (x-r < cx < x+w+r)
  • Расстояние между любым углом прямоугольника и (cx, cy) меньше, чем r.

Как я уже сказал в своем комментарии, столкновение между кругами еще проще, потому что вам нужно только проверить, меньше ли расстояние между центрами суммы радиусов.

Для прямоугольников, не выровненных по осям, решение немного сложнее. Даны четыре вершины прямоугольника (A, B, C, D); если хоть одно из следующего верно, то происходит коллизия:

  • (x < cx < x+w) и (y < cy < y+h)
  • intersectCircle(A, B, cx, cy, r)
  • intersectCircle(B, C, cx, cy, r)
  • intersectCircle(C, D, cx, cy, r)
  • intersectCircle(D, A, cx, cy, r)

Псевдокод функции intersectCircle таков:

intersectCircle(P1, P2, a, b, r):
    x1, y1 = P1
    x2, y1 = P2
    p = abs((x1-x2)*(a-x1)+(y2-y1)*(b-y1))
    q = sqrt((x1-x2)^2 + (y1-y2)^2)
    return r > p/q

Эта функция основана на формуле этот математический ответ, который, безусловно, является самым простым, который я нашел.

person Community    schedule 03.03.2013
comment
Сам посадочный модуль можно вращать, поэтому оси, к сожалению, не всегда параллельны. Есть ли способ изменить это, чтобы он все еще работал? - person Dave Clarke; 04.03.2013
comment
@ swiss196 swiss196 Я обновил ответ для прямоугольников, не выровненных по оси, надеюсь, это поможет. - person A. Rodas; 10.03.2013