iOS SpriteKit - столкновения и контакты не работают должным образом
Иногда в моих программах SpriteKit мои коллизии и контакты (с использованием SKPhysicsBody) не запускаются или не работают должным образом. Я думаю, что настроил все, что мне нужно, но я все еще не получаю правильное взаимодействие. Как я могу легко проверить, что будет сталкиваться с тем, что и какие органы настроены для создания контактов?
1 ответ
Чтобы помочь диагностировать проблемы такого типа, я написал функцию, которую можно вызывать из любого места и которая будет анализировать текущую сцену и создавать список того, с какими узлами сталкиваются, с какими другими и о каких столкновениях будет уведомлена моя сцена.
Функция является автономной и ей не нужно ничего рассказывать об узлах в сцене.
Функция выглядит следующим образом:
//MARK: - Analyse the collision/contact set up.
func checkPhysics() {
// Create an array of all the nodes with physicsBodies
var physicsNodes = [SKNode]()
//Get all physics bodies
enumerateChildNodesWithName("//.") { node, _ in
if let _ = node.physicsBody {
physicsNodes.append(node)
} else {
print("\(node.name) does not have a physics body so cannot collide or be involved in contacts.")
}
}
//For each node, check it's category against every other node's collion and contctTest bit mask
for node in physicsNodes {
let category = node.physicsBody!.categoryBitMask
// Identify the node by its category if the name is blank
let name = node.name != nil ? node.name : "Category \(category)"
let collisionMask = node.physicsBody!.collisionBitMask
let contactMask = node.physicsBody!.contactTestBitMask
// If all bits of the collisonmask set, just say it collides with everything.
if collisionMask == UInt32.max {
print("\(name) collides with everything")
}
for otherNode in physicsNodes {
if (node != otherNode) && (node.physicsBody?.dynamic == true) {
let otherCategory = otherNode.physicsBody!.categoryBitMask
// Identify the node by its category if the name is blank
let otherName = otherNode.name != nil ? otherNode.name : "Category \(otherCategory)"
// If the collisonmask and category match, they will collide
if ((collisionMask & otherCategory) != 0) && (collisionMask != UInt32.max) {
print("\(name) collides with \(otherName)")
}
// If the contactMAsk and category match, they will contact
if (contactMask & otherCategory) != 0 {print("\(name) notifies when contacting \(otherName)")}
}
}
}
}
Вам также необходимо проверить эти 3 вещи:
- сцена должна быть
SKPhysicsContactDelegate
- Вы должны установить
physicsWorld.contactDelegate = self
- Вам необходимо реализовать один из дополнительных методов
SKPhysicsContactDelegate
:
didBeginContact
didEndcontact
Функция должна быть вызвана после того, как вы настроили все свои картинки - обычно в конце didMoveToView
работает:
checkPhysics()
Когда я вызываю эту функцию с конца моего didMoveToView
в моем проекте Swift я получаю следующий вывод:
Необязательный ("shape_blueSquare") сталкивается с Необязательным ("категория 2147483648") Необязательный ("shape_blueSquare") сталкивается с необязательным ("shape_redCircle") Необязательный ("shape_blueSquare") сталкивается с необязательным ("shape_purpleSquare") необязательным ("shape_blueSquare") с Необязательным ("shape_yellowTriangle") Необязательный ("shape_redCircle") сталкивается с Необязательным ("Категория 2147483648") Необязательный ("shape_redCircle") сталкивается с Необязательным ("shape_blueSquare") Необязательный ("shape_redCircle") уведомляет при обращении к Необязательному ("shape_purpleS") Необязательный ("shape_redCircle") сталкивается с Необязательным ("shape_yellowTriangle") Необязательный ("shape_redCircle") уведомляет при контакте Необязательный ("shape_yellowTriangle") Необязательный ("shape_purpleSquare") сталкивается с Необязательным ("Категория 2147483648") необязательным ("shape_pur")) сталкивается с Optional ("shape_yellowTriangle"). Optional ("shape_yellowTriangle") сталкивается со всем, что было введено didBeginContact для Optional("shape_purpleSquare") и Optional ("shape_redCircle") didBeginContact введен для необязательных ("shape_purpleSquare") и необязательных ("shape_redCircle") didBeginContact введен для необязательных ("shape_yellowTriangle") и необязательных ("shape_redCircle")
Категория 2147483648 - это моя граница края, и у нее нет имени. Я дал ему эту категорию, чтобы соответствовать его столкновению BitMask
Пожалуйста, не стесняйтесь попробовать эту функцию и дайте мне знать, если она полезна или есть какие-либо ситуации, с которыми она не справляется.