SKSpriteNode 的 "didMove#to" 是什么?

What's the "didMove#to" for SKSpriteNode?

当然,在一个场景中...

class DotScene: SKScene {
    
    override func didMove(to view: SKView) {
        
        print("this scene is now in place...")

调用 didMove#to 时,您知道场景就位。

(这就像 ViewDidAppear,你可以说。)

但是

我不知道如何知道 精灵 已添加到场景中。

class Spaceship: SKSpriteNode {
    
    func wtf() {
        
        this sprite has just been added to a scene
        (such as with .childNode)
        this sprite is now in place in the scene ...

只是 - 必须 - 一个提醒您节点已成功出现的调用。

这是什么?

在 SpriteKit 中,无法在将节点添加到场景时检测自定义精灵内部 class。这已被排除在外,因为您可以通过 addChildmoveToParent 控制何时将精灵添加到场景中。

Spritekit 不符合 MVC 架构,而 UIKit 则符合。 didMoveToView 存在的原因之一是因为视图的目的只是作为输出显示。控制器负责处理视图背后的代码。现在视图控制器可以用来从视图中调用 presentScene,但是如果我们正在转换,我们真的不知道场景在什么时候正式附加到视图。 (除此之外还有其他原因,我只举一个例子)

现在要解决这个问题,您可以实施键值观察 (KVO),并监听 scene 何时设置。为此,只需执行以下操作:

override init()
{
    super.init()
    addObserver(self, forKeyPath: #keyPath(SKNode.scene), options: [.old, .new, .initial], context: nil)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) 
{
    if keyPath == #keyPath(SKNode.scene) && self.scene != nil 
    {
        didAttachToScene()
    }
}

func didAttachToScene()
{
}

deinit 
{
    removeObserver(self, forKeyPath: #keyPath(SKNode.scene))
}

现在,我还没有对此进行测试,我目前处于 windows 环境中,但如果这不起作用,您可以在节点附加到父节点时收听(我实际上已经这样做了使用 KVO,所以我知道这是可能的),并推断我们是否以这种方式在场景中,因为节点必须有一个父节点才能有资格在场景中。

override init()
{
    super.init()
    addObserver(self, forKeyPath: #keyPath(SKNode.parent), options: [.old, .new, .initial], context: nil)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) 
{
    if keyPath == #keyPath(SKNode.parent) && self.scene != nil 
    {
        didAttachToScene()
    }
}

func didAttachToScene()
{
}

deinit 
{
    removeObserver(self, forKeyPath: #keyPath(self.parent))
}