SKSpriteNode, added to/removed from parent hook

后端 未结 2 1609
耶瑟儿~
耶瑟儿~ 2021-01-13 06:18

Is there any (best practice) way within the class to hook the events when a SKSpriteNode (or SKNode) is added onto and removed from a parent node?

相关标签:
2条回答
  • 2021-01-13 06:57

    Kobold Kit adds the callback methods didMoveToParent and willMoveFromParent to all KK*Node classes.

    This is achieved by subclassing all SK*Node classes and overriding the corresponding addChild and removeChild methods and their variants. They then call the category methods above on the node, depending on whether the node was added or removed.

    Unfortunately we can not subclass SKNode in order to add methods to all SKNode classes - all the other SK*Node will still have the original SKNode as its parent. Besides subclassing you could also add custom addChild/removeChild methods (let's say addNode/removeNode) in an SKNode category and use only these. They would then send a willAdd/didRemove message to the node before calling the original addChild/removeChild implementation.

    Theoretically this could also be done by swizzling the addChild/removeChild methods on the SKNode class. But if I remember correctly that's what I initially tried, and it didn't work - I don't remember why exactly, one of the reasons could have been that subclasses of SKNode could implement their own versions of addChild/removeChild without calling the super implementation, or calling the super implementation simply does not run the swizzled methods. Another reason might be that internally the addChild/removeChild methods are directly forwarded to the underlying C++ Sprite Kit engine rather than being passed upwards in the SKNode class hierarchy.

    0 讨论(0)
  • 2021-01-13 06:58

    Without the need of Kobold Kit, you can sub-class a SKSpriteNode (or any SKNode for the fact) and extend the removeFromParent function that SKNodes own.

    For example:

    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;
    }
    

    As for adding a child, since you add a child as such (in most cases) [self addChild:node]; you'll need to extend the addChild in the view you are adding to. For example you'll add the following to your MyScene.m, since we are adding the sprite to that view

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

    This is pretty much what Steffen Itterheim did to acheive this functions, as he explained in his posting.

    0 讨论(0)
提交回复
热议问题