Sprite kit SKSpriteNode,添加到父钩子中/从父钩子中删除

Sprite kit SKSpriteNode,添加到父钩子中/从父钩子中删除,sprite-kit,Sprite Kit,在父节点上添加和删除SKSpriteNode(或SKNode)时,类中是否有任何(最佳实践)方法来钩住事件?将回调方法didMoveToParent和willMoveFromParent添加到所有KK*节点类中 这是通过对所有SK*节点类进行子类化并覆盖相应的addChild和removeChild方法及其变体来实现的。然后,根据是否添加或删除了节点,它们在节点上调用上面的category方法 不幸的是,我们不能将SKNode子类化,以便向所有SKNode类添加方法-所有其他SK*节点仍将原始S

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

将回调方法
didMoveToParent
willMoveFromParent
添加到所有KK*节点类中

这是通过对所有SK*节点类进行子类化并覆盖相应的
addChild
removeChild
方法及其变体来实现的。然后,根据是否添加或删除了节点,它们在节点上调用上面的category方法

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


理论上,这也可以通过在SKNode类上滑动addChild/removeChild方法来实现。但如果我没记错的话,那就是我最初尝试的,但没有成功-我不记得确切的原因,其中一个原因可能是SKNode的子类可以实现自己版本的addChild/removeChild,而无需调用超级实现,或者调用超级实现根本不运行swizzled方法。另一个原因可能是,内部的AdHoe/ReaveBooT方法直接转发到基础C++ SpRITE套件引擎,而不是在SkNoB类层次结构中被传递到上。

< P>不需要KOBODID套件,可以将SkScript(或任何SkNoad)分为子类。并扩展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
-(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;
}
MyScene.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
-(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在帖子中解释的那样,这正是Steffen Itterheim实现这些功能所做的

这里的问题是,可能还有一些其他的变体,比如insertChild,以及parent的removeChild。要抓住所有这些可能会变得很棘手。无论如何,像游戏中的暂停弹出层(可能是一个sknode或skspritenode)这样的操作是很难正确进行的。如果你正在子类化sknode/skspritenode,那就不难了。但是tbh,如果你依赖addChild的钩子,你可能会走错方向。底线是,Sprite Kit可能很大,但它缺少的是开源社区…你可以对iOS SDK说同样的话@琼尼