iOS SpriteKit - 冲突和联系人无法正常工作

时间:2016-04-12 10:40:44

标签: swift sprite-kit collision-detection skphysicsbody

有时在我的SpriteKit程序中,我的碰撞和联系人(使用SKPhysicsBody)不会按预期触发或工作。我想我已经设置了我需要的一切,但我仍然没有得到正确的互动。如何轻松检查哪些内容会与设置的内容碰撞哪些内容以及生成联系人?

1 个答案:

答案 0 :(得分:5)

为了帮助诊断这些类型的问题,我编写了一个可以从任何地方调用的函数,它将分析当前场景并生成一个列表,列出哪些节点与哪些节点发生碰撞以及哪些碰撞将通知我的场景

该功能是独立的,不需要告诉场景中的节点。

功能如下:

            //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)")}
                }
            }
        }  
    }

您还需要检查这三件事:

  1. 场景必须SKPhysicsContactDelegate
  2. 您必须设置physicsWorld.contactDelegate = self
  3. 您需要实现其中一个可选方法 SKPhysicsContactDelegate
  4. didBeginContact

    didEndcontact

    一旦你设置了所有照片,就应该调用该函数 - 通常在didMoveToView结束时工作:

    checkPhysics()
    

    当我在练习Swift项目中从didMoveToView的末尾调用此函数时,我得到以下输出:

      

    可选(“shape_blueSquare”)与Optional(“类别”)发生冲突   2147483648“)可选(”shape_blueSquare“)与之碰撞   可选(“shape_redCircle”)可选(“shape_blueSquare”)与之碰撞   可选(“shape_purpleSquare”)可选(“shape_blueSquare”)冲突   with Optional(“shape_yellowTriangle”)可选(“shape_redCircle”)   与Optional冲突(“Category 2147483648”)   可选(“shape_redCircle”)与Optional(“shape_blueSquare”)发生碰撞   可选(“shape_redCircle”)在联系时通知   可选(“shape_purpleSquare”)可选(“shape_redCircle”)发生碰撞   with Optional(“shape_yellowTriangle”)可选(“shape_redCircle”)   联系Optional时通知(“shape_yellowTriangle”)   可选(“shape_purpleSquare”)与Optional(“类别”)发生冲突   2147483648“)可选(”shape_purpleSquare“)与之冲突   可选(“shape_yellowTriangle”)可选(“shape_yellowTriangle”)   与所有输入的bebeContact相冲突   可选(“shape_purpleSquare”)和Optional(“shape_redCircle”)   didBeginContact输入Optional(“shape_purpleSquare”)和   输入的选项(“shape_redCircle”)didBeginContact   可选(“shape_yellowTriangle”)和Optional(“shape_redCircle”)

    类别2147483648是我的边界,它没有名称。我给它这个类别来匹配它的collisionBitMask

    请随意尝试此功能,让我知道它是否有用或是否有任何情况无法处理。