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

Posted

技术标签:

【中文标题】SKSpriteNode 子类:移除所有关节的方法【英文标题】:SKSpriteNode subclass: method to remove all joints 【发布时间】:2014-12-25 17:29:01 【问题描述】:

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

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

到目前为止效果很好。 然后我到了我想从关节中释放节点的地步。 According to the SKPhysicsBody docs there is a property called "joints" which is an array holding SKPhysicsJoint objects. 我认为这正是我需要的,但我无法遍历实例的关节并将它们从物理世界中删除。为了完成这项工作,我向我的自定义 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 的共同财产提出意见。更具体地说:如何使用(投射?)数组中的项目以便能够将它们从场景的 SKPhysicsWorld 中移除。

【问题讨论】:

如果我没记错的话,关节数组保存了内部 PKPhysicsJoint 实例,所以转换会失败,因为 SKPhysicsJoint 只是一个创建实际关节实例的便利类。不知道如何用 swift 解决这个问题,在 objc 中它只允许你转换为 skphysicsjoint 或 id。但似乎你只需要一种方法来以一种不会抱怨的方式快速铸造关节。 @LearnCocos2D 你是对的。关节数组包含 PKPhysicsJoint 对象。即使文档说它“拥有一组 SKPhysicsJoint 对象”。 For objective-c I found a tutorial that solves a similar problem (as you said), by casting the joint-array-items and removing them from the physics-world。有趣的是,同样的教程存在于使用另一种方法的"how to do it with swift"-version 中。 【参考方案1】:

我花了更多时间对此进行调查。这是我想出的:

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

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

每次我向场景的 SKPHysicsWorld 添加一个关节时,我也会将它添加到 SKNNode 本身的关节数组中。虽然在我想将其转换为 SKPhysicsJoint 时迭代 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)
    

这似乎不是完成这项工作的最优雅的方式,因为已经有一个框架管理的数组承诺是相同的东西。但我无法使用它,这暂时有效。

【讨论】:

以上是关于SKSpriteNode 子类:移除所有关节的方法的主要内容,如果未能解决你的问题,请参考以下文章

SKSpriteNode 从场景中移除后如何停止音频(Swift)?

仅当 SKSpriteNode 是 Fruit 类型时才用手指移动 SKSpriteNode(SKSpriteNode 的子类)

使用 Swift 创建 SKSpriteNode 子类

子类化的 SKSpriteNode 触摸事件被忽略

SpriteKit 触摸

移动时如何访问 SKSpriteNode 子类的对象(Swift)