【问题标题】:iOS SpriteKit - collisions and contacts not working as expected [closed]iOS SpriteKit - 碰撞和联系人无法按预期工作[关闭]
【发布时间】:2016-04-12 10:40:43
【问题描述】:

有时在我的 SpriteKit 程序中,我的碰撞和接触(使用 SKPhysicsBody)不会触发或按预期工作。我想我已经设置了我需要的一切,但我仍然没有得到正确的交互。

我是否可以编写一些代码来检查什么会与什么发生冲突,以及设置了哪些主体来生成联系人?

【问题讨论】:

  • 这类问题其实适合Code Review
  • 这仅适用于代码审查,前提是代码按预期工作并且 OP 想要审查......从这个问题的声音来看,他不想审查,他想要一个错误检查他的代码...
  • 实际上,我并不真正希望我的代码被审查,因为 OI 认为它有效,但我试图发布一些可以帮助解决碰撞/接触问题的人的内容。也许我应该发布一个问题,说明我遇到了问题,然后我的 checkPhysics 函数作为答案?
  • Stack Overflow 是一个问答网站,这里没有问题。我想您可以将代码发布为您自己问题的答案,问题是“如何诊断 SpriteKit 碰撞检测错误?”
  • 除非您在物理节点阵列上使用过滤器,否则这会变得非常慢非常快,并且在测试期间实际上会伤害您,低 FPS 意味着跳帧可能导致对象相互穿过,而不是触发没有联系

标签: sprite-kit collision-detection 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)")}
                }
            }
        }  
    }

你还需要检查这三件事:

  1. 场景必须是SKPhysicsContactDelegate
  2. 您必须设置physicsWorld.contactDelegate = self
  3. 您需要实现以下可选方法之一 SKPhysicsContactDelegate:

didBeginContact

didEndcontact

设置完所有图片后,应调用该函数 - 通常在 didMoveToView 作品的末尾:

checkPhysics()

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

Optional("shape_blueSquare") 与 Optional("Category 2147483648") 可选("shape_blueSquare") 与 Optional("shape_redCircle") Optional("shape_blueSquare") 与 可选(“shape_purpleSquare”)可选(“shape_blueSquare”)碰撞 与可选(“shape_yellowTriangle”)可选(“shape_redCircle”) 与可选碰撞(“类别 2147483648”) Optional("shape_redCircle") 与 Optional("shape_blueSquare") 碰撞 Optional("shape_redCircle") 联系时通知 可选(“shape_purpleSquare”)可选(“shape_redCircle”)碰撞 与可选(“shape_yellowTriangle”)可选(“shape_redCircle”) 联系 Optional("shape_yellowTriangle") 时通知 Optional("shape_purpleSquare") 与 Optional("Category 2147483648") 可选(“shape_purpleSquare”)与 可选的(“shape_yellowTriangle”) 可选的(“shape_yellowTriangle”) 与 didBeginContact 输入的所有内容发生冲突 可选(“shape_purpleSquare”)和可选(“shape_redCircle”) 为 Optional("shape_purpleSquare") 输入了 didBeginContact 和 Optional("shape_redCircle") didBeginContact 输入 可选(“shape_yellowTriangle”)和可选(“shape_redCircle”)

类别 2147483648 是我的边缘边界,它没有名称。我给它这个类别以匹配它的碰撞位掩码

请随意尝试这个功能,如果它有用或者有什么情况它不能处理,请告诉我。

【讨论】:

  • 这是一个值得 github 使用的工具!
猜你喜欢
  • 1970-01-01
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多