如何一起动画多个SKSpriteNode?

时间:2014-05-05 11:28:22

标签: ios objective-c animation sprite-kit

我对SpriteKit很新。我有一组节点需要一起移动到每个节点的不同点,并且在完成所有动画的动画之后我想做其他事情。

我之前使用UIView组件进行此操作。 [UIView animateWithDuration:completion:]块提供了我需要的东西。但是在SpriteKit中,每个节点都有自己的动作和动画。我找不到精灵节点的任何块动画。所以我无法控制动画的完成。

希望,我很清楚。提前谢谢。

1 个答案:

答案 0 :(得分:3)

有一些 SKAction 类方法可能会引起关注。第一个是 runBlock:,第二个是组: (这允许操作并行运行)

您可以使用 runAction:完成

在具有完成处理程序的节点上运行操作

以下代码将每个'动画操作'以及完成块放在'block action'中。然后将阻止操作放入'组操作'。最后,群组行动被告知要运行。这会导致每个块操作同时启动。每个块操作的完成处理程序调用名为 checkCompletion 的方法。此方法通过在节点上调用 hasActions 来检查节点(具有特定名称属性值)仍然是动画。因为调用 checkCompletion 方法的节点将返回YES,如果只有一个节点返回YES,则完成所有动画。

以下使用两个节点演示了这一点,但它可以使用两个以上的节点。

// assuming two SKNode subclasses 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];

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...

     }
}

不幸的是,由于块操作持续时间是瞬时的,因此以下操作无效。因此,在这种情况下群体行动的持续时间也是瞬时的。这就是 checkCompletion 方法的原因。

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