【问题标题】:Setting physics body in initializer of SKSpriteNode custom subclass doesn't work在 SKSpriteNode 自定义子类的初始化程序中设置物理体不起作用
【发布时间】:2017-11-08 01:10:10
【问题描述】:

我正在使用 SpriteKit 构建游戏,并且正在使用 Xcode 的场景编辑器来设置我的 GameScene

场景包含一个Player,我将它作为颜色精灵拖到场景中,并在Custom Class 字段中填写为mygame.Player

我有一个名为 Player 的 SKSpriteNode 自定义子类,在这个类中,我在应用调用的初始化程序中设置了物理属性。

class Player: SKSpriteNode {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        print(self)
        self.physicsBody = SKPhysicsBody(rectangleOf: self.size)
        self.physicsBody?.restitution = 0
        self.physicsBody?.isDynamic = true
        self.physicsBody?.affectedByGravity = true
        self.physicsBody?.velocity = CGVector(dx: 50, dy: 0)
        print(self.physicsBody)
    }

}

在我的GameScene.swift 文件中,我可以引用播放器,所以这个链接有效。

override func didMove(to view: SKView) {
    player = childNode(withName: "player") as! Player
    print(player)
    print(player.physicsBody)
}

这实际上完美地打印了玩家和物理体。

<SKSpriteNode> name:'player' texture:['nil'] position:{0, 0} scale:{1.00, 1.00} size:{100, 100} anchor:{0.5, 0.5} rotation:0.00
Optional(<SKPhysicsBody> type:<Rectangle> representedObject:[<SKSpriteNode> name:'player' texture:['nil'] position:{0, 0} scale:{1.00, 1.00} size:{100, 100} anchor:{0.5, 0.5} rotation:0.00])

但是,即使我已将场景设置为具有重力,玩家也永远不会在场景中移动!为了让玩家真正移动,我需要在 GameScene 中的 didMove(to:) 函数中添加另一行代码,再次设置 PhysicsBody:

player.physicsBody = SKPhysicsBody(rectangleOf: player.size)

这里发生了什么?为什么在初始化程序中设置我的 Player 的物理主体不起作用?

【问题讨论】:

    标签: ios sprite-kit


    【解决方案1】:

    因为有一个 bug,即在物理世界存在之前创建物理体时,它没有正确设置在世界中。

    作为临时解决方案,请尝试:

    class Player: SKSpriteNode {
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            print(self)
            DispatchQueue.main.asyncAfter(deadline: .now() + 1)
            {
                self.physicsBody = SKPhysicsBody(rectangleOf: self.size)
                self.physicsBody?.restitution = 0
                self.physicsBody?.isDynamic = true
                self.physicsBody?.affectedByGravity = true
                self.physicsBody?.velocity = CGVector(dx: 50, dy: 0)
                print(self.physicsBody)
            }
        }
    
    }
    

    延迟创造身体,直到世界存在。

    如果可行,那么你需要想出一种更优雅的方式来在世界存在之后创建身体。

    【讨论】:

    • 你是对的——SpriteKit 上有一个错误。我很高兴你告诉我这件事!
    • 值得注意的是,根据我的测试,您无需等待。即使延迟低至 0.01 秒,这也为我解决了这个问题。将其设置为第二个会停止正在配置的节点并影响用户体验
    • 我不建议延迟,这是一个临时解决方案,以确定是否是时间问题
    猜你喜欢
    • 2016-08-14
    • 2017-04-30
    • 1970-01-01
    • 2015-06-18
    • 2012-06-26
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 2015-01-11
    相关资源
    最近更新 更多