Обнаружение столкновений для повернутых растровых изображений на Android

Мне нужно точное по пикселям обнаружение столкновений для моей игры для Android. Я написал некоторый код для обнаружения столкновения с «обычными» растровыми изображениями (не повернутыми); работает отлично. Однако я не понимаю его для повернутых растровых изображений. К сожалению, в Java нет класса для повернутых прямоугольников, поэтому я реализовал его самостоятельно. Он содержит положение четырех углов по отношению к экрану и описывает точное местоположение/слой своего растрового изображения; называется "itemSurface". Мой план решения проблемы обнаружения заключался в следующем:

  1. Обнаружение пересечения различных itemSurfaces
  2. Расчет площади перекрытия
  3. Установите эти области по отношению к вышестоящему элементу. Поверхность/растровое изображение.
  4. Сравните каждый отдельный пиксель с соответствующим пикселем другого растрового изображения.

Ну, у меня проблемы с первым и вторым. У кого-нибудь есть идея или код? Возможно, в Java/Android-библиотеках уже есть код, но я его просто не нашел.


person user1524194    schedule 13.07.2012    source источник


Ответы (1)


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

Реализуйте функцию static boolean isCollision, которая сообщит вам, есть ли столкновение между одним прямоугольником и другим. Перед тем, как взять лист бумаги, проведите некоторую геометрию, чтобы узнать точные формулы. По соображениям производительности не оборачивайте прямоугольник в какой-либо класс Rectangle, просто используйте примитивные типы, такие как двойные и т.д.

Затем (псевдокод):

for (every rectangle a)
  for (every rectangle b)
    if (a != b && isCollision(a, b))
      bounce(a, b)  

Это O(n^2), где n — количество прямоугольников. Есть лучшие алгоритмы, если вам нужно больше производительности. Функция bounce меняет векторы движущихся прямоугольников так, чтобы имитировать столкновение. Если вес объектов был одинаковым (вы можете приблизить вес к размеру прямоугольников), вам просто нужно поменять местами два вектора скорости.

Для корректного отскока элементов вам может понадобиться хранить вспомогательную таблицу boolean alreadyBounced[][], чтобы определить, какие прямоугольники не нуждаются в изменении своих векторов после отскока (столкновения), потому что они уже были отброшены.

Еще один совет:

Если вы делаете игру под Android, вы должны следить за тем, чтобы не выделять память во время игры, потому что это быстрее вызовет GC, который занимает много времени и замедляет вашу игру. Я рекомендую вам посмотреть это видео и связанные с ним. Удачи.

person Adam Stelmaszczyk    schedule 13.07.2012
comment
Проблема в том, что я использую растровые изображения, которые частично прозрачны. Вот почему мне приходится сравнивать каждый пиксель, чтобы коллизия выглядела настоящей. Область перекрытия необходима, чтобы знать, какие пиксели растрового изображения необходимо сравнивать. (Пожалуйста, поправьте меня, если есть более эффективный способ) Более того, точные формулы - моя главная проблема :D. Я уже ищу их много часов. Я надеюсь, что кто-то уже знает алгоритм. PS: Большое спасибо за совет :) - person user1524194; 13.07.2012