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

7

我创建了一个SKSpriteNode的子类。我使用类型为SKPhysicsJointLimit的连接将该类的实例连接在一起。我在我的GameScene中的didEndContact(contact: SKPhysicsContact)函数中实现这个功能。

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

这目前运作得很好。然后我到了想要释放节点与关节的点上。根据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)
            }
        }
    }

调用方法在println()语句后失败,并显示消息“Swift dynamic cast failed”。我真的很希望您能就如何使用SKPhysicsBody的joint属性提供建议。更具体地说:如何使用(转换?)数组中的项以便能够从场景的SKPhysicsWorld中删除它们。

如果我没记错的话,关节数组保存了内部的PKPhysicsJoint实例,所以强制转换会失败,因为SKPhysicsJoint只是一个方便的类来创建实际的联接实例。不确定如何在Swift中解决这个问题,在Objective-C中可以允许你将其转换为SKPhysicsJoint或者id。但是似乎你只需要一种方法来以一种Swift不会抱怨的方式转换关节。 - CodeSmile
@LearnCocos2D 您说得对。joints数组包含PKPhysicsJoint对象。尽管文档中说它“包含SKPhysicsJoint对象的数组”。对于Objective-C,我找到了一个教程,通过将joint数组项强制转换并将它们从物理世界中删除来解决类似的问题(正如您所说)。有趣的是,同一教程还存在于另一个版本的“How to do it with Swift”中,该版本使用了另一种方法。 - silmor-vie
1个回答

3

我花了更多的时间来调查这个问题。这是我的结论:

我决定给我的SKSpriteNode子类添加一个属性,自己管理连接。

    var joints: [SKPhysicsJointLimit]
override init(){
    ...
    self.joints = []
    ...
}

每当我将一个连杆添加到场景的SKPHysicsWorld时,我也会将其添加到SKNNode本身的连杆数组中。虽然在迭代SKPHysicsBody的连杆数组时失败了(请参见问题),但在迭代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)
    }
}

这似乎不是最优雅的完成任务的方式,因为已经有一个由框架管理的数组承诺是同样的东西。但是我无法利用它,现在这个方法可以使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接