Ответ 1
Вы не можете получить желаемое поведение, потому что вы не правильно задали маски разряда категории, контакта и столкновений. Вот пример того, как вы можете настроить это:
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 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 - Маска, определяющая, какие категории тел вызывают уведомления о пересечении с текущим физическим телом.
Когда два тела имеют одинаковое пространство, каждая маска категории bodys протестированы против другой контактной маски bodys, выполнив логическую И операция. Если либо сравнение приводит к ненулевому значению, Объект SKPhysicsContact создается и передается в мир физики делегировать. Для достижения наилучшей производительности только установите бит в маске контактов для взаимодействий, которые вас интересуют.
collisionBitmask - Маска, которая определяет, какие категории физических тел могут столкнуться с этим физическим телом.
Когда два физических тела контактируют друг с другом, может произойти столкновение. Эта маска столкновения bodys сравнивается с другой категорией bodys маски, выполняя логическую операцию И. Если результат отличен от нуля значение, на это тело влияет столкновение. Каждый орган независимо выбирает, хочет ли он быть затронутым другим телом. Для Например, вы можете использовать это, чтобы избежать вычислений столкновений, которые делают незначительные изменения скорости bodys.
Итак, в основном, чтобы настроить все это, вы должны спросить себя:
Хорошо, у меня есть зеленый шар, красный шар и предметы на стене. Между телами я хочу, чтобы произошли столкновения, или когда я хочу зарегистрировать контакты? Я хочу, чтобы зеленый и красный шар сталкивались друг с другом и сталкивались с стенами. Не проблема. Сначала я правильно настрою категории, а затем поставлю такие бит-бит:
greenBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory; //greenBall will collide with greenBall, redBall and a wall
redBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory
wall.collisionBitMask = GreenBall | RedBall
Теперь я хочу обнаружить, когда происходят некоторые контакты (в didBeginContact
: method)... Но я не хочу получать уведомления обо всех возможных контактах, а скорее получать уведомления о контактах между шарами (контакты между шарами и стеной будет проигнорировано). Поэтому давайте установим contactTestBitMasks
для достижения этой цели:
greenBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
redBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
И что это. Важно, когда вы не используете обнаружение контактов, вы не должны устанавливать contactTestBitMask
. Это связано с соображениями производительности. Если вам не требуется обнаружение столкновений, и вас интересует только обнаружение контактов, вы можете установить collisionBitMask = 0
.
Важно:
Удостоверьтесь, что вы установили делегат физического мира, чтобы использовать методы didBeginContact
и didEndContact
:
self.physicsWorld.contactDelegate = self; //where self is a current scene
Надеюсь, это немного поможет.