【问题标题】:Updating SKNodes outside update() of scene在场景的 update() 之外更新 SKNode
【发布时间】:2016-07-10 19:22:17
【问题描述】:

我很惊讶 SKScene 类中的更新方法实际上并不是从 SKNode 继承的。对我来说,所有 SKNode 能够自我更新似乎是合乎逻辑的(例如,当它不再显示时,将其从场景中移除等等)。我认为这将有助于使实例分离独立实体(无依赖关系,无意外行为)如果仅在场景中保留更新背后有其他逻辑,请解释。

所以我想知道是否值得使用计时器(以 1/60 的时间间隔重复)向我的自定义 SKNodes 添加自定义更新(甚至可能是一个将其添加到所有 SKNodes 的扩展)。但是,我想这会占用大量内存。所以我想问一下这方面是否有一些“最佳实践”。如果计时器在每一帧触发而不是强制它每秒触发 60 次,也许计时器会起作用。

【问题讨论】:

    标签: ios swift performance sprite-kit sknode


    【解决方案1】:

    绝对不要使用计时器。

    SpriteKit 具有明确定义的更新周期,并且每种更新(逻辑、物理、图形)都应在明确定义的时间范围内发生。

    如果您真的想在节点中编写更新逻辑,那么最好的解决方案是创建自己的 update 方法,然后从 GameScene 手动调用它。

    让我们看看(可能的)结构化方法

    协议

    protocol Updatable: class {
        func update(currentTime: NSTimeInterval)
    }
    

    使您的精灵/节点可更新

    class Player: SKSpriteNode, Updatable {
    
        func update(currentTime: NSTimeInterval) {
            // your logic goes here
        }
    }
    

    将更新从场景转发到节点

    class GameScene: SKScene {
    
        private var updatables = [Updatable]()
    
        override func didMoveToView(view: SKView) {
            let player = Player()
            updatables.append(player)
            self.addChild(player)
        }
    
        override func update(currentTime: NSTimeInterval) {
            updatables.forEach { $0.update(currentTime) }
        }
    }
    

    如您所见,我正在使用Updatables 的数组。在将新的Updatables 添加(或删除)到场景图中时,您还应该注意将它们添加(或删除)到数组中。

    虽然肯定有可能每帧搜索整个场景图,但从性能的角度来看,这将是非常糟糕的。

    这是正确的方法吗?

    我个人不喜欢在SKNodeSKSpriteNode 的子类中编写这种代码。

    我通常创建一个Logic 类。此类是从 GameScene 接收 update 事件的类。它还接收其他“逻辑事件”,例如:

    1. gameStarted
    2. touchesBegan
    3. touchesEnded

    该类包含游戏的纯游戏逻辑

    它类似于您可以在棋盘游戏中找到的说明手册,它与游戏实体的图形表示完全无关。

    在理想情况下,我可以从我的 SpriteKit 游戏中提取 Logic 类,并将其与另一个框架或什至与同一游戏的(非电子)棋盘游戏版本一起使用。

    【讨论】:

    • 我几乎一提交问题就想到了这一点。但是,我管理可更新的方法是不同的。我没有保留一个数组,而是遍历所有子节点并使用 if let 检查该节点是否是可更新的。这安全吗?
    • @YoussefSami 搜索所有Updatables 是安全的但是有两个巨大的缺点。 1) 从性能的角度来看,它非常糟糕。这意味着您正在通过场景图执行搜索的每一帧。它非常昂贵,最好像我向您展示的那样缓存此列表。 2) 请记住,某些Updatables 不能是GameScene 的直接子代。他们可能是GameScene 的孩子的孩子。所以这不是一个简单的for。这是对场景图的全面访问。
    • @LucaAngeletti 缓存updatables 是个好主意。您是否介意扩展 Logic 类的含义,或者您能指出一个示例项目吗?这是缓存updatables 的更好模式吗?我有一些在场景中很少出现但需要更新的对象。我的对象不是搜索场景图,而是使用重复的updateSKAction,每次调用之间有一个短的wait。这感觉类似于 Timer 方法,你说它不好。
    • @muZero 太多问题需要评论。请在 StackOverflow 上创建新问题并在此处添加链接,我会看看。
    猜你喜欢
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    相关资源
    最近更新 更多