Comment animer plusieurs SKSpriteNode set?

Je suis assez nouveau à SpriteKit . J'ai un set de nœuds qui doivent se déplacer set à un point différent pour chaque nœud et après que l'animation soit terminée pour chacun d'entre eux, je voudrais faire autre chose.

Je faisais cela avec des composants UIView auparavant. Un [UIView animateWithDuration:completion:] fournissait la chose dont j'avais besoin. Mais dans SpriteKit chaque nœud a sa propre action et SpriteKit seul. Je n'ai trouvé aucune animation de bloc pour les noeuds de sprites. Donc je ne peux pas contrôler l'achèvement de l'animation.

J'espère, je suis clair. Merci d'avance.

Il y a quelques methods de class SKAction qui pourraient vous intéresser. Le premier étant runBlock: et le second étant group: (ceci permet d'exécuter les actions en parallèle) .

Vous pouvez exécuter des actions sur les nœuds avec un gestionnaire d'achèvement à l'aide de runAction: completion:

Le code suivant place chaque 'action d'animation' , ainsi que le bloc d'achèvement dans une 'action de bloc' . Les actions de bloc sont ensuite placées dans une «action de groupe» . Enfin, l'action de groupe est dit de fonctionner. Cela provoque chaque action de bloc pour démarrer en même time. Le gestionnaire d'achèvement de chaque action de bloc appelle une méthode nommée checkCompletion . Cette méthode vérifie les noeuds (avec une valeur de propriété de nom spécifique) toujours animée en appelant hasActions sur le noeud. Étant donné que le noeud qui a appelé la méthode checkCompletion renverra YES, si un seul noeud renvoie YES, toutes les animations sont effectuées.

Ce qui suit démontre cela en utilisant deux nœuds, mais cela fonctionnera pour plus de deux.

 // assuming two SKNode subclasss named 'node1' and 'node2' AND 'self' is an SKScene subclass // assign each animating node the same name (used in checkCompletion method) node1.name = @"animating"; node2.name = @"animating"; // in this example both nodes will animate to the origin CGPoint origin = CGPointMake(0.0, 0.0); // make move actions for nodes SKAction *shortMove = [SKAction moveTo:origin duration:1.2]; SKAction *longMove = [SKAction moveTo:origin duration:4.8]; // wrap nodes in their own separate block action SKAction *moveNode1 = [SKAction runBlock:^{ [node1 runAction:shortMove completion:^{ NSLog(@"shortMove complete"); [self checkCompletion]; }]; }]; SKAction *moveNode2 = [SKAction runBlock:^{ [node2 runAction:longMove completion:^{ NSLog(@"longMove complete"); [self checkCompletion]; }]; }]; // put block actions in a group action SKAction *groupAction = [SKAction group:@[moveNode1, moveNode2]]; // execute group action [self runAction:groupAction]; 

méthode checkCompletion –

 - (void)checkCompletion { __block int currentlyHasActions = 0; // check for all actions complete on animating nodes [self enumerateChildNodesWithName:@"animating" usingBlock:^(SKNode *node, BOOL *stop){ if ([node hasActions]) { currentlyHasActions++; // prevent unnecessary enumeration if (currentlyHasActions > 1) { *stop = YES; } } }]; if (currentlyHasActions == 1) { NSLog(@"Actions Finished!!!"); // execute completion code here... } } 

Malheureusement, ce qui suit ne fonctionnera pas car la durée d'une action de blocage est instantanée. Par conséquent, la durée de l'action de groupe dans ce cas est également instantanée. C'est la raison de la méthode checkCompletion .

 [self runAction:groupAction completion:^{ // completion code here... :( }];