Вы не можете получить желаемое поведение, потому что вы не задали правильные маски разряда категории, контакта и столкновения. Вот пример того, как вы можете установить эту работу:
greenBall.physicsBody?.categoryBitMask = GreenBallCategory //Category is GreenBall
greenBall.physicsBody?.contactTestBitMask = RedBarCategory | WallCategory //Contact will be detected when GreenBall make a contact with RedBar or a Wall (assuming that redBar's masks are already properly set)
greenBall.physicsBody?.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory //Collision will occur when GreenBall hits GreenBall, RedBall or hits a Wall
redBall.physicsBody?.categoryBitMask = RedBallCategory //Category is RedBall
redBall.physicsBody?.contactTestBitMask = GreenBarCategory | GreenBallCategory | WallCategory //Contact will be detected when RedBall make a contact with GreenBar , GreenBall or a Wall
redBall.physicsBody?.collisionBitMask = RedBallCategory | GreenBallCategory | WallCategory //Collision will occur when RedBall meets RedBall, GreenBall or hits a Wall
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody = borderBody
self.physicsBody?.friction = 0
borderBody.contactTestBitMask = RedBallCategory | GreenBallCategory //Contact will be detected when red or green ball hit the wall
borderBody.categoryBitMask = WallCategory
borderBody.collisionBitMask = RedBallCategory | GreenBallCategory // Collisions between RedBall GreenBall and a Wall will be detected
Я рекомендовал бы вам прочитать документацию о categoryBitMask, который представляет собой маску, которая определяет, какие категории принадлежит физике тело:
Каждый физическому телу в сцене можно присвоить до 32 различных категорий , каждый из которых соответствует бит в битовой маске. Вы определяете значения маски, используемые в вашей игре . В сочетании с параметрами collisionBitMask и contactTestBitMask вы определяете, какие физические тела взаимодействуют друг с другом, и когда ваша игра уведомляется об этих взаимодействиях.
contactTestBitMask - Маска, определяющая, какие категории тел вызывают уведомления о пересечении с текущим физическим телом.
Когда два тела один и то же место, категория маска каждого тела является проверяется на контактной маску другого тела, выполняя логическую операцию И . Если любое сравнение приводит к ненулевому значению, создается объект SKPhysicsContact и передается делегату физика. Для лучшей производительности, только установленные биты в контактах маски для взаимодействий вы заинтересованы в
collisionBitmask -. Маска, которая определяет, какие категории физических тел могут столкнуться с этой физикой телом.
Когда два физических тела контактируют друг с другом, может возникнуть столкновение. Маска столкновения этого тела сравнивается с маской другого тела , выполняя логическую операцию И. Если результатом является ненулевое значение , на это тело влияет столкновение. Каждый орган независимо выбирает, хочет ли он быть затронутым другим телом. Например, для вы можете использовать это, чтобы избежать вычислений столкновений, которые бы приводили к незначительным изменениям скорости тела.
Так в основном, чтобы настроить все это, вы должны задать себе что-то вроде:
Хорошо, у меня есть зеленый шар, и красный шар, и объекты стены на сцене. Между телами я хочу, чтобы произошли столкновения, или когда я хочу зарегистрировать контакты? Я хочу, чтобы зеленый и красный шар сталкивались друг с другом и сталкивались с стенами. Не проблема. Я первый настроит категории должным образом, а затем обращу столкновения битовых масок, как это:
greenBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory; //greenBall will collide with greenBall, redBall and a wall
redBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory
wall.collisionBitMask = GreenBall | RedBall
Теперь я хочу, чтобы обнаружить, когда некоторые контакты происходят (в didBeginContact
: метод) ... Но я не хочу получать уведомления обо всех возможных контактах, а скорее получать уведомления о контактах между шарами (контакты между шарами и стеной будут проигнорированы). Таким образом, позволяет установить contactTestBitMasks
для достижения этой цели:
greenBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
redBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
И это все. Важно то, что если вы не используете обнаружение контактов, вы не должны устанавливать contactTestBitMask
. Это связано с соображениями производительности. Если вам не требуется обнаружение столкновений, и вас интересует только обнаружение контактов, вы можете установить collisionBitMask = 0
.
Важен:
Убедитесь, что вы установили ФИЗИК мир контакт делегат для того, чтобы использовать didBeginContact
и didEndContact
методы:
self.physicsWorld.contactDelegate = self; //where self is a current scene
Надеется, что это помогает немного.
Удивительный ответ, большое вам спасибо за то, что нашли время, чтобы написать все это. Он работает отлично. «Задайте себе эту» часть определенно выяснила, на что я был смущен. Спасибо, так много! – Noowoo
Как насчет того, если у вас больше 32? – cnzac
@Abcdefg Как вы можете обнаружить конец столкновения в функции didEnd? – Marin