SKSpriteNode子类:删除所有关节的方法

sil*_*vie 6 ios sprite-kit skphysicsbody skphysicsjoint swift

我创建了一个SKSpriteNode的子类.我将该类的实例与SKPhysicsJointLimit类型的关节连接在一起.我在我的GameScene中的didEndContact(联系方式:SKPhysicsContact)中执行此操作:

var joint = SKPhysicsJointLimit.jointWithBodyA(contact.bodyA, bodyB: contact.bodyB, anchorA: pos1!, anchorB: pos2!)
self.physicsWorld.addJoint(joint)
Run Code Online (Sandbox Code Playgroud)

这到目前为止运作良好.然后我来到了我想要从关节中释放节点的地步.根据SKPhysicsBody文档,有一个名为"joints"的属性,它是一个包含SKPhysicsJoint对象的数组.我认为这正是我所需要的,但我无法迭代实例的关节并将它们从physicsWorld中删除.为了完成这项工作,我在自定义SKSpriteNode子类中添加了一个方法.

func freeJoints(world: SKPhysicsWorld){
        if let joints = self.physicsBody?.joints {
            for joint in joints{
                println("found a joint: \(joint)")
                // example print:
                //found a joint: <PKPhysicsJointRope: 0x7fbe39e95c50>
                world.removeJoint(joint as SKPhysicsJoint)
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

在println()语句之后调用该方法失败,并显示消息"Swift dynamic cast failed".我非常感谢您对如何使用SKPhysicsBody的联合财产的看法.更具体地说:如何使用(强制转换)数组中的项目,以便能够从场景的SKPhysicsWorld中删除它们.

sil*_*vie 3

我花了更多的时间来调查这个问题。这就是我想出的:

我决定向我的 SKSpriteNode 子类添加一个属性并自己管理关节

    var joints: [SKPhysicsJointLimit]
override init(){
    ...
    self.joints = []
    ...
}
Run Code Online (Sandbox Code Playgroud)

每次我向场景的 SKPHysicsWorld 添加关节时,我也会将其添加到 SKNNode 本身的关节数组中。当迭代 SKPHysicsBody 的关节数组失败(参见问题)时,我想将其转换为 SKPhysicsJoint,但在迭代 SKPhysicsJointLimit 项目数组时,从物理世界中删除项目会按预期工作:

func freeJoints(world: SKPhysicsWorld){
        for item in self.joints{
            println("removing item from physics world \(item)")
            world.removeJoint(item)
        }
        self.joints.removeAll(keepCapacity: false)
    }
}
Run Code Online (Sandbox Code Playgroud)

这似乎不是完成这项工作的最优雅的方法,因为已经有一个框架管理的数组承诺做同样的事情。但我无法使用它,目前这有效。