检测何时将 SKNode 添加为子节点

Posted

技术标签:

【中文标题】检测何时将 SKNode 添加为子节点【英文标题】:Detect when SKNode is added as child 【发布时间】:2016-01-08 10:34:41 【问题描述】:

我有一个用作数据容器的 Polygon 类,但出于调试目的,我想通过将多边形作为子节点添加到 SKNode 来绘制多边形。当我这样做时,我希望 Polygon 对象为其自身添加边框精灵子项。由于性能原因,我只想在将多边形作为子节点添加到另一个节点时添加这些精灵。

Polygon 对象本身是否可以检测到它已添加到场景中,或者我是否需要在添加到场景后通过额外的createSprites 调用来告诉它?

我想我可以轮询父属性,但我正在寻找事件驱动的东西。

【问题讨论】:

【参考方案1】:

在 Swift 中,您可以为继承的类的属性定义属性观察者

您可以观察到自定义 SKNode 子类的 parent 属性的变化,如下所示:

class MyNode : SKNode 

    override var parent: SKNode? 
        didSet 
             // parent node changed; do something
        
    


编辑: 就像我在 cmets 中提到的,在 Objective-C(您不能使用属性观察器)中,您可以改用键值观察 (KVO),并观察 @987654323 中的变化@的parent属性:

实际代码:

- (instancetype) init

    if (self = [super init])
        // REGISTER for KVO
        [self addObserver:self 
               forKeyPath:@"parent" 
                  options:NSKeyValueObservingOptionNew
                  context:NULL];
    

    return self;


- (void) dealloc 

    // UNREGISTER from KVO
    [self removeObserver:self forKeyPath:@"parent" context:NULL];


// Method that is called when any keyPath you subscribed to is modified
- (void)observeValueForKeyPath:(NSString *)keyPath
                  ofObject:(id)object
                    change:(NSDictionary *)change
                   context:(void *)context

    // (Check keypath in case you are observing several different
    //  properties. Otherwise, remove if statement:)

    if ([keyPath isEqualToString:@"parent"]) 

        // parent node changed; do something
    

【讨论】:

谢谢。我有点模糊。我的问题涉及objective-c。而且我不认为我想扩展这些基类。我一直在寻找内置的东西。但也许没有这样的解决方案。 然后,使用 Key-Value Observing 并在属性 'parent' 更改值时得到通知。 Xcode 12.5.1 中出现惊人的编译错误:Cannot observe read-only property 'parent'; it can't change。你看?父节点不能更改。哇! 这实际上只对答案的第一部分是公平的,KVO 效果很好。【参考方案2】:

在 Objective-C 中你可以这样做:

[node addObserver:self forKeyPath:@"parent" options:NSKeyValueChangeOldKey context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
    //logic here

或者在这种情况下,只需继承 SKNode 并覆盖 setParent:

【讨论】:

以上是关于检测何时将 SKNode 添加为子节点的主要内容,如果未能解决你的问题,请参考以下文章

iOS 7 SpriteKit 游戏 - 保存加载游戏时出错:'尝试将 nil 节点添加到父节点:<SKNode> 名称:'(null)'

如何在 SpriteKit 中一次引用多个 SKNode?

尝试添加已经有父节点的 SKNode

SpriteKit/Objective-C - 节点内的触摸检测

错误:尝试添加已经有父节点的 SKNode

转换回 gamescene.swift 会导致错误“'尝试添加一个已经有父节点的 SKNode”