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 вещи:

  1. сцена должна быть SKPhysicsContactDelegate
  2. Вы должны установить physicsWorld.contactDelegate = self
  3. Вам необходимо реализовать один из дополнительных методов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

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

Другие вопросы по тегам