SKSpriteNode,添加到/从父节点钩子中移除

5

有没有在类内部钩子事件的(最佳实践)方法,当一个SKSpriteNode(或SKNode)被添加到父节点时,以及从父节点中移除时?

2个回答

4

不需要使用Kobold Kit,您可以对SKSpriteNode(或任何SKNode)进行子类化,并扩展SKNodes拥有的removeFromParent函数。

例如:

FLSprite.m:

#import "FLSprite.h"

@implementation FLSprite

-(void)removeFromParent {
    [super removeFromParent];
    NSLog(@"I print when I'm Removed");
    //here's where you'll add your hooking functions
}

@end

MyScene.m:

-(id)initWithSize:(CGSize)size {    
    if (self = [super initWithSize:size]) {
    FLSprite* sprite = [FLSprite spriteNodeWithColor:[UIColor blackColor] size:CGSizeMake(200, 100)];
        [sprite setPosition:CGPointMake(100.0, 50.0)];
        [self addChild:sprite];
        [sprite removeFromParent];

    }
    return self;
}

关于添加子节点,由于你通常是这样添加子节点的 [self addChild:node];,所以你需要扩展你要添加到的视图中的 addChild。例如,由于我们将精灵添加到了该视图中,因此您需要在 MyScene.m 中添加以下内容:

-(void)addChild:(SKNode *)node {
    [super addChild:node];
    NSLog(@"added child");
}

这基本上就是Steffen Itterheim在他的文章中所解释的实现方法。


这里的问题是可能还有其他几个变体,比如insertChild,以及像parent's removeChild这样的东西。要捕捉所有这些可能会变得棘手。无论如何,做像游戏内暂停弹出层(可能是sknode或skspritenode)这样的事情很难做到完美。 - Jonny
如果你正在子类化SKNode/SKSpriteNode,那么这并不会很棘手。但说实话,如果你依赖于addChild钩子,那么你可能正在错误的方向上进行事情。 - John Riselvato

3

Kobold Kit将回调方法didMoveToParentwillMoveFromParent添加到所有KK*Node类中。

这是通过对所有SK*Node类进行子类化并覆盖相应的addChildremoveChild方法及其变体来实现的。然后,根据节点是添加还是删除,它们会在节点上调用上述类别方法。

不幸的是,我们无法对SKNode进行子类化以添加方法到所有SKNode类 - 所有其他SK*Node仍将具有原始的SKNode作为其父项。除了子类化之外,您还可以在SKNode类别中添加自定义addChild/removeChild方法(比如addNode/removeNode),并仅使用这些方法。然后,在调用原始addChild/removeChild实现之前,它们将向节点发送willAdd/didRemove消息。

理论上,这也可以通过在SKNode类上交换addChild/removeChild方法来实现。但是如果我记得正确的话,那就是我最初尝试的方式,但它没有起作用——我不记得为什么,其中一个原因可能是SKNode的子类可以实现自己的addChild/removeChild版本而不调用超级实现,或者调用超级实现只是不运行交换的方法。另一个原因可能是内部的addChild/removeChild方法直接转发到底层的C++ Sprite Kit引擎,而不是向上传递到SKNode类层次结构中。


底线是,Sprite Kit 可能很强大,但它缺乏开源社区的支持... - Jonny
3
iOS SDK也可以这样说... @Jonny - John Riselvato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接