2013-12-09 4 views
1

У меня проблема с тем, как SpriteKit разрешает столкновения между двумя телами. Я разрабатываю игру, в которой узлы спрайтов динамически добавляются на экран в случайных положениях. У всех этих спрайтов есть физические тела, которые сталкиваются друг с другом. На более высоких уровнях игры есть много этих спрайтов, а иногда и новый спрайт, который он добавляет поверх другого (что является правильным поведением до тех пор, пока столкновение разрешается плавно). В Cocos2d + Box2d в этой ситуации столкновение разрешается плавно. Оба спрайта осторожно перемещаются в противоположных направлениях, пока они больше не сталкиваются. Это выглядит очень хорошо, даже если есть много таких столкновений, анимация движения плавная и FTP высок. Однако, на SpireKit все выглядит несколько иначе. Когда новое тело добавляется поверх другого, с точки зрения пользователя он не перемещается для разрешения столкновения - вместо этого он «телепортируется». Нет никакого плавного движения шпилей, они просто переориентируются таким образом, что они больше не будут сталкиваться. Это выглядит неплохо для игрока, даже игра работает 60 кадров в секунду. Я прочитал в документации Apple:SpriteKit, разрешать конфликты плавно, как в Cocos2d

Столкновение используется для предотвращения взаимного проникновения двух объектов. Когда один орган ударяет по другому телу, Sprite Kit автоматически вычисляет результаты столкновения и применяет импульс к телам при столкновении.

Но похоже, что это не так, как описано. Apple говорит мне, что при столкновении происходит импульс, применяемый к телам, которые сталкиваются друг с другом, но в реальной жизни похоже, что тела «телепортированы» (мгновенно перемещаются в то место, которое больше не вызывает столкновения). Может быть, сила, приложенная к телам, настолько сильна, что вы не можете видеть движение объектов. Интересно, есть ли способ улучшить такое поведение в SpriteKit, поэтому он больше похож на Cocos2d + Box2d. В конце концов, SpriteKit от Apple основан на Box2d.

+2

Пожалуйста, дайте мне знать, если вы выясните какие-либо обновления по этому вопросу. Он не изменился, и время от времени у моей игры будет немного «дрожания», и мой игрок будет телепортироваться по той же причине. – lespommes

+1

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

ответ

1

На самом деле перекрывающиеся тела не являются физическими двигателями поведения, которые пытаются моделировать или включить в свой дизайн как функцию - наблюдаемое поведение является лишь побочным эффектом и, возможно, сильно зависит от параметров тела (определенно «пулями», или «непрерывное» обнаружение столкновения, usesPreciseCollisionDetection в терминах Sprite Kit).

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

«Мягкий» способ, который вы описываете, на самом деле может быть очень проблематичным для регулярного разрешения конфликтов. Особенно, если тела спроектированы так, чтобы быть жесткими, т. Е. Тело игрока не должно проникать сквозь стену или пол даже немного. Для Sprite Kit имеет смысл попытаться избежать этого поведения в целом, это обычно более проблематично, чем полезно или желательно.

Итак, ответ: попробуйте различные варианты параметров, чтобы увидеть, можете ли вы получить желаемое поведение. Но я не удивлюсь, если в Sprite Kit на самом деле невозможны два перекрывающихся тела, которые медленно раздвигаются друг от друга. То есть, если телам просто не хватает места для полного отделения.

+0

Хорошее объяснение. Какие параметры вы имеете в виду, что я мог бы настроить? Я попробовал 'usePreciseCollisionDetection', но это ничего не меняет в моем случае. – Darrarski

1

Я нашел решение в своем случае. К сожалению, моя ситуация может быть иной.

Для меня проблема заключалась в том, что когда было больше одного физического тела, связанного с физическим телом игроков, он телепортировал игрока. В моей игре, когда игрок схватил коллекционный предмет прямо в тот момент, когда атака нападает на игрока и перекрывает его (так как коллекционные и атакующие физические тела перекрывают физическое тело игроков), он телепортирует игрока. Это было даже с collisionBitMask = 0 для всех из них.

Я смог организовать контактBitMasks таким образом, чтобы 2 контакта не регистрировались сразу для двух вещей из одного и того же спрайта. Это трудно объяснить без примера:

Примечание: collisionBitMask = 0 для всех из них (игрок только столкнулся с землей)

Что было раньше:

плеер

contactBitMask = Атака | Коллекционная

Атака

contactBitMask = 0

Коллекционная

contactBitMask = 0

Что установил его:

Игрок

contactBitMask = Атака

Атака

contactBitMask = 0

Коллекционная

contactBitMask = Игрок

После того, как вы изменили его, вы ничего не телепортируетесь, и физические тела могут пересекаться, ничего не получится.

Смежные вопросы