【问题标题】:How to animate multiple SKSpriteNode together?如何一起为多个 SKSpriteNode 设置动画?
【发布时间】:2014-05-05 11:28:22
【问题描述】:

我对@9​​87654321@ 很陌生。我有一组节点需要一起移动到每个节点的不同点,在所有节点的动画完成后,我想做其他事情。

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

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

【问题讨论】:

  • 您可以为每个节点分配并运行一个 SKAction 以按顺序移动到不同的点。它不会在完全相同的时间,但在执行一行所需的时间之间存在差异代码?
  • 是的,我现在正在这样做。但是我想在所有节点的动画完成后做点什么。但我找不到这样做的方法。

标签: ios objective-c animation sprite-kit


【解决方案1】:

有几个可能感兴趣的 SKAction 类方法。第一个是 runBlock:,第二个是 group: (这允许操作并行运行)

您可以使用完成处理程序在节点上运行操作 runAction: completion:

以下代码将每个“动画动作”连同完成块放在一个“块动作”中。然后将阻止操作放入 “组操作”。最后,组动作被告知运行。这会导致每个阻止操作同时开始。每个块操作的完成处理程序调用一个名为 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... :(
}];

【讨论】:

  • 不幸的是,在某些情况下,SKAction 从未完成并且未执行完成块,我已经在自己的代码中实现了您的解决方案。此解决方案是否有任何副作用?
  • 如何在 swift 3 中实现所有这些?例如,如果您希望一堆节点同时或按顺序执行操作?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 2016-12-29
相关资源
最近更新 更多