2013-10-29 10 views

risposta

3

Kobold Kit aggiunge i metodi di richiamata didMoveToParent e willMoveFromParent a tutte le classi di nodi KK *.

Questo è ottenuto sottoclassando tutte le classi di nodi SK * e sovrascrivendo i corrispondenti metodi addChild e removeChild e le loro varianti. Quindi chiamano i metodi di categoria sopra sul nodo, a seconda che il nodo sia stato aggiunto o rimosso.

Sfortunatamente non è possibile creare una sottoclasse di SKNode per aggiungere metodi a tutte le classi di SKNode - tutti gli altri nodi SK * avranno ancora lo SKNode originale come genitore. Oltre alla sottoclasse, potresti anche aggiungere metodi addChild/removeChild personalizzati (diciamo addNode/removeNode) in una categoria SKNode e usarli solo. Avrebbero quindi inviato un messaggio willAdd/doneRemove al nodo prima di chiamare l'implementazione originale addChild/removeChild.

In teoria, è possibile eseguire anche il swizzling dei metodi addChild/removeChild nella classe SKNode. Ma se ricordo bene è quello che inizialmente ho provato, e non ha funzionato - non ricordo perché esattamente, una delle ragioni potrebbe essere che le sottoclassi di SKNode potevano implementare le proprie versioni di addChild/removeChild senza chiamare il super implementazione, o chiamare la super implementazione semplicemente non esegue i metodi swizzled. Un altro motivo potrebbe essere che internamente i metodi addChild/removeChild sono inoltrati direttamente al motore di C++ Sprite Kit sottostante piuttosto che essere passati verso l'alto nella gerarchia della classe SKNode.

+0

Bottom line, Sprite Kit potrebbe essere grande e grande ma quello che manca è la comunità open source ... – Jonny

+3

Puoi dire la stessa cosa su iOS SDK ... @Jonny –

4

Senza la necessità di Kobold Kit, è possibile sottoclasse un SKSpriteNode (o qualsiasi SKNode per il fatto) ed estendere la funzione removeFromParent di proprietà di SKNodes.

Ad esempio:

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

Per quanto riguarda l'aggiunta di un bambino, dal momento che si aggiunge un bambino in quanto tale (nella maggior parte dei casi) [self addChild:node]; è necessario estendere lo addChild nella vista re aggiungendo a. Per esempio si aggiungerà quanto segue al MyScene.m, dal momento che stiamo aggiungendo lo sprite a quella vista

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

Questo è più o meno quello Steffen Itterheim ha fatto a raggiungere questo funzioni, come ha spiegato nel suo distacco .

+0

Il problema qui è che ci sono probabilmente un paio di altre varianti come insertChild, e anche roba come removeChild dei genitori. Potrebbe diventare complicato catturare tutti quelli. Comunque, fare cose come un livello popup di pausa nel gioco (che probabilmente è uno sknode o skspritenode) è difficile da ottenere. – Jonny

+0

non se la sottoclasse SKNode/SKSpriteNode, non sarebbe difficile. ma tbh, se stai facendo affidamento su un hook con addChild, probabilmente stai andando sulle cose nel modo sbagliato. –