【问题标题】:Calling method when a node is removed from an SKScene从 SKScene 中删除节点时的调用方法
【发布时间】:2013-11-26 18:16:02
【问题描述】:

有没有办法挂钩到 Sprite Kit 中的 SKNode 生命周期?具体来说,我想在节点从场景中移除时执行一些代码。

我想更详细地解决的用例: 我有一些相互交互的节点,我希望他们能够收到发生在其他节点上的某些事件的通知。例如,想象一个游戏,您可以在场景中点击一个节点,该节点的详细信息将出现在 HUD 上。当节点从场景中移除时,我希望 HUD 消失。 我计划使用 NSNotificationCenter 作为通知引擎。 每当一个节点从场景中移除时,我想发布一个通知。最简单的方法是绑定到 SKNode 上的生命周期方法(我的节点是 SKSpriteNode 的子类),例如 nodeWasRemovedFromParent,但我没有找到任何这样的方法。

如何做到这一点?

我通过在我的 SKSpriteNode 子类中重写 removeFromParent 方法并在调用超级实现之前发布通知来编写自己的解决方案。我不确定 removeFromParent 方法是否总是会被调用。例如,当我改变场景时它会被调用吗?

谢谢。

【问题讨论】:

    标签: ios objective-c sprite-kit


    【解决方案1】:

    您需要对每个节点类进行子类化。如您所说,覆盖 removeFromParent 方法。仅使用子类版本,否则您的代码将不会生效。

    此外,您还需要覆盖 removeAllChildrenremoveChildrenInArray:,或者永远不要使用它们。

    场景变化时不会调用removeFromParent方法。相反,覆盖场景的willMoveFromView: 方法并递归地向注册的观察者或简单的所有子节点发送消息。使用场景的枚举函数来做到这一点。请注意,我不能 100% 确定 willMoveFromView 上的场景的孩子是否仍然依附,我认为他们会。

    不幸的是,不可能只对 SKNode 进行子类化,然后期望子类的代码适用于所有其他节点类,因为这些子类直接来自 SKNode,而不是您的自定义 SKNode 子类。因此,如果您需要在删除时通知它,您还需要子类化并将此代码添加到每个 SK*Node 子类中。

    有关示例,请参见 KoboldKit 节点类,它使用宏将此“覆盖”代码注入 SK*Node 子类以避免重复代码。实际功能在 KKNodeShared 中:https://github.com/KoboldKit/KoboldKit/tree/master/KoboldKit/KoboldKitFree/Framework/Nodes/Framework

    【讨论】:

    • 谢谢,也会看看例子。当然,我不希望为每个节点调用 SKNode 子类(我们称之为 NotifyingNode)removeFromParent。我计划将我的自定义节点类的超类更改为 NotifyingNode,以便它可以工作。另外我不需要这个功能在所有节点上工作,只需要我的自定义节点。因此,当按照您的建议对 willMoveFromView 中的子项进行迭代时,我可以检查每个子项是否是 NotifyingNode 的子类。
    • @LearnCocos2d 是否可以在这里使用类别而不是 SubClassing ?不确定通过类别覆盖方法是否存在限制。
    • 这就是问题所在,您不能(可靠地)用类别覆盖现有方法。另外,即使您对其进行了调整,Sprite Kit 中似乎也没有维护类层次结构,ObjC 类只是 C++ 类的包装器。因此,SKSpriteNode 似乎直接调用了底层 C++ 引擎,而不是 SKSpriteNode 在 SKNode 上调用 removeFromParent 的(swizzled)超级实现。
    • 这个答案是最新的吗?还是没有办法在 iOS 8 中加入 SpriteKit 的生命周期?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    相关资源
    最近更新 更多