SKSpriteNode,添加到父钩子或从父钩子删除

问题描述:

在SKSpriteNode(或SKNode)添加到父节点和从父节点删除时,类中是否有任何(最佳实践)方式来挂钩事件?SKSpriteNode,添加到父钩子或从父钩子删除

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

这是通过继承所有SK *节点类并覆盖相应的addChildremoveChild方法及其变体来实现的。然后他们在节点上调用上面的类别方法,具体取决于节点是添加还是删除。

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

理论上这也可以通过调整SKNode类的addChild/removeChild方法来完成。但是如果我没有记错,那是我最初尝试过的,并且它不起作用 - 我不记得为什么,究竟是什么原因之一,SKNode的子类可以在不调用super的情况下实现自己的addChild/removeChild版本实现或调用超级实现不会运行混合方法。另一个原因可能是内部addChild/removeChild方法直接转发到底层C++ Sprite Kit引擎,而不是在SKNode类层次结构中向上传递。

+0

底线,Sprite Kit可能很大很好,但它缺少的是开源社区... – Jonny

+3

你可以说iOS SDK的同样的东西... @Jonny –

如果不需要Kobold套件,您可以对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"); 
} 

这差不多就是斯特芬Itterheim做以达致这功能,正如他在发帖解释。

+0

这里的问题可能有几个其他变体像insertChild,还有像父母的removeChild之类的东西。抓住所有这些可能会变得棘手。无论如何,像游戏中的暂停弹出层(这可能是一个sknode或skspritenode)的东西是很难得到正确的。 – Jonny

+0

如果您是SKNode/SKSpriteNode的子类,则不会很棘手。但是tbh,如果你依赖于addChild的钩子,你可能会以错误的方式处理事情。 –