使用必需的init(nscoder)时从代码设置物理主体

Dis*_*ath 3 physics initialization ios sprite-kit swift

我正在尝试利用init?(编码器aDecoder:NSCoder)函数,以便我可以在我的sks文件中创建子类sprite.

我可以在sks文件中设置物理体,但是对于我正在使用的也有圆角的矩形精灵,它不能很好地工作.由于圆角,在使用init函数之前,我在代码中设置了物理体,并将宽度设置为略小于正方形宽度(当我的英雄从正方形滑落时,那里没有间隙圆角是......

我知道我可以使用alpha蒙版物理体来获得相同的效果,除此之外,当我的英雄在块上时似乎有1个px'的间隙,并且看起来不太好.

想知道为什么我不能设置这个物理机构,以及我如何能够做到这一点或绕过它?

谢谢你的帮助!!!

更新:

    required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    if let p = userData?.value(forKey: "col") as? String {
        setup(p)
        print("working")
    }
}
func setup(_ col: String) {
    setupPhysics()
    //allSprites.append(self)
Run Code Online (Sandbox Code Playgroud)

在setupPhysics我有:

override func setupPhysics() {
    physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: frame.width - 4, height: frame.height - 1))
...more code...
}
Run Code Online (Sandbox Code Playgroud)

这是我的精灵代码,我在sks文件中正确设置了它...

我评论了对所有精灵的追加,以便我可以证明它不起作用.随着append取消注释,sprite会被添加到allSprites,然后在Scene文件中的didMove函数中,它遍历allSprites并运行setupPhysics():

  func setup(_ col: String) {
    //setupPhysics()
    allSprites.append(self)

// scene file
    func setupAllSpritesPhysics() {
    for sprite in allSprites { sprite.setupPhysics() }
}
Run Code Online (Sandbox Code Playgroud)

@ Knight0fDragon:

你提到这是一个丑陋的修复.鉴于它不会以"正确"的方式运作,我不同意.目前我没有足够的精灵在场景加载中造成任何延迟.如果是这样的话,我可以在将来调查这个问题.

我承认我没有尝试过你提到的方法,因为我不想为我创建的每个精灵创建一个子节点,以便即使它可以解决这个问题.到目前为止,我很欣赏这个建议.

Kni*_*gon 5

为了使这个工作与SKS文件,我会添加一个儿童SKNode与您想要的身体的尺寸,然后在自定义类代码,做

required init(coder aDecoder:NSCoder){
    super.init(coder:aDecoder)
    if let child = childNode(withName:"child"), let physicsBody = child.physicsBody{
       self.physicsBody = physicsBody
       child.removeFromParent()
    }
}
Run Code Online (Sandbox Code Playgroud)

我们在这里做的是将物理身体从孩子转移到父母,然后杀死孩子.这使我们的代码更具动态性,并使设计与功能分离.

好吧,来自苹果的漂亮小虫子.

发生的事情是在NSCoder发生的时候物理世界不存在,而不是将物理体附加到精灵体上时,它确实存在,它决定缓存位于SKS文件中的物理体,这是为什么它不起作用.

因此解决这个问题的一个非常方便的方法是实现一个worldNode(无论如何都是这样做的好方法,特别是如果你想创建一个暂停屏幕),然后删除它然后在sceneLoad中重新添加它:

class GameScene: SKScene,SKPhysicsContactDelegate {
    lazy var worldNode : SKNode = { self.childNode(withName:"//worldNode")!}()

    override func sceneDidLoad() {
        worldNode.removeFromParent()
        addChild(worldNode)
    }
}
Run Code Online (Sandbox Code Playgroud)