2D обнаружение столкновений

11

Давайте предположим, что я использую этот персонаж.

птица
(источник: iconbug.com )

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

Я думал о том, чтобы внутри объекта была какая-то структура данных четырехугольного дерева, представляющая части изображения. Каждый лист может быть или false(в случае, если он покрывает белое / прозрачное пространство снаружи птицы) или true(в случае, если он представляет область птицы, например, клюв, глаз и т. Д.). Затем каким-то образом протестируйте единственное препятствие на сцене для столкновения с птицей.

Но мои проблемы в моем подходе:

  1. Я не знаю, как инициализировать дерево квадов.
  2. После инициализации четырехугольного дерева я не уверен, как пройти и использовать его, когда препятствие находится в пределах координат изображения.

Как бы вы сделали обнаружение столкновений с не квадратными персонажами?

Л.Е .: Другой подход, который я видел, заключался в использовании нескольких ограничивающих рамок. Например, у меня есть одна или несколько ограничительных рамок для клюва, затем несколько из них для волос или хвоста. Но это может стать утомительным. Если это правильный подход в моем случае, как бы я сгенерировал эти ограничивающие рамки? Я сомневаюсь, что я должен иметь их в своей программе.

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

асинхронной
источник
2
Общее замечание: я бы использовал и ограничивающую рамку, и более детальную проверку: выборочная проверка будет иметь более высокую производительность, поэтому вы хотите, чтобы она выполнялась как можно реже. Поэтому сначала отметьте ограничивающий прямоугольник и, только если он поражен, идите на уровень глубже и проверьте свой более детальный подход (каким бы он ни был).
Филипп Альгайер
Спасибо, я все равно планировал это сделать, но я не совсем уверен, какой должна быть «детальная проверка». :)
async
1
Единственная важная деталь отсутствует: что вы хотите с ней делать? Вы заботитесь о точных столкновениях? Вы рады, чтобы приблизить персонажа с кругом? Вы хотите, чтобы частицы пыли сталкивались с глазами персонажа отдельно от остальных?
Анко
@Anko Как вы можете приблизить эту форму с помощью круга? Я забочусь о достаточно точных столкновениях - не совсем с точностью до пикселя, но что-то, что будет выглядеть хорошо / естественно -.
async
1
Как это . Что означают «хорошее» и «естественное»? Это философский вопрос?
Анко

Ответы:

12

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

Не переусердствуйте.

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

Jonkel
источник
3
Да, просто сделайте небольшой массив из нескольких фигур, если одна фигура не покроет его. Например: i.imgur.com/Dd4yyGN.png
MichaelHouse
Спасибо Jonkel & @ Byte56. Использование нескольких форм кажется правильным решением в моей ситуации. Простая в реализации, точная и быстрая. Не могу поверить, что я прыгнул прямо на четверные деревья, не задумываясь об этом! Э - э.
асинхронное
Круглый коллайдер для тела и прямоугольник для клюва для дополнительной точности.
Кролтан
14

Двухэтапный процесс проверки

На первом шаге вы проверяете ограничивающий прямоугольник , и если там нет столкновений, тогда тест завершен. Если есть столкновение, вы переходите ко второму проходу

На втором проходе , если вам нужна более высокая точность и вы хотите действительно идеальное решение для пикселов, то вы можете сделать именно это, проходной контроль для пикселов.

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

  1. Вычислите площадь пересечения между этим одним объектом на сцене и птицей, создав простой прямоугольник пересечения на обоих изображениях.
  2. В пределах этого пересечения убедитесь, что каждый пиксель имеет альфа-значение> 0 на ОБА изображениях
  3. Если такие пиксели существуют, вы столкнулись. В противном случае нет

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

альфа-канал из изображения

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

«Более тонкий» подробный ограничивающий прямоугольник столкновения Анко предложил:

более подробная ограничительная рамка

PS: если ваше изображение имеет ореол, эффект или другой не-0 альфа-канал вокруг него, с которым вы не хотите сталкиваться, порог алгоритма можно легко отрегулировать, чтобы приспособить это

codemonkey
источник
1
Спасибо! Но в конце концов мне не понадобится идеальная точность пикселей. Отличный ответ, хотя, будет полезно позже.
async
конечно, приятель, да, столкновение с идеальным пикселем почти всегда является излишним, за исключением игр, которые действительно в этом нуждаются (например, 2D-бойцы)
codemonkey
3

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

| grad
источник
0

Может быть, вы могли бы использовать какой-нибудь шаткий полигон / краевой коллайдер.

Не уверен, как именно это будет работать, но:

два объекта: объект 1: птица (o1), объект 2: вещь, которая может ударить птицу (o2)

1) Определите ограничивающую фигуру, которая является многоугольником, который подходит близко к первому рассматриваемому объекту (o1).

2) Получите ребра o1, o2, которые могли бы столкнуться без возможности столкновения без прохождения o2 через o1 или наоборот.

С положением и размером фигуры (o2) вы, вероятно, могли бы изолировать ребра (от o1), в которые невозможно попасть, потому что они находятся «за» другим ребром (из o1), который ближе к o2. Если у вас был прямоугольный треугольник, гипотенуза которого обращена вверх и вправо, и прямоугольник, приближающийся к нему прямо (с длинной стороной вдоль оси x), то вы можете указать, какие ребра пропустить, так как значения их начала и конца y оба либо выше или ниже прямоугольника.

3) Определите, совпадает ли одна из точек на краю o2 с точкой на любом из ребер o1, выбранных на шаге 2.

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

Джереми Хартон
источник