当前位置: 首页 > 知识库问答 >
问题:

如何将多个SKSpriteNode一起设置动画?

米楷
2023-03-14

我对SpriteKit非常陌生。我有一组节点,需要一起移动到每个节点的不同点,在所有节点的动画完成后,我想做一些其他的事情。

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

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

共有1个答案

越英韶
2023-03-14

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

可以使用runAction:completion: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];

检查完成方法-

- (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... :(
}];
 类似资料:
  • 目标是同时为多个SCNNodes设置动画,然后在所有动画完成后调用完成块。平行动画的持续时间相同,因此如果同时开始,将在同一时间完成。 因此,这个答案建议对Sprite Kit使用函数,但由于类缺少,因此没有模拟场景中的Kit。 一个选项是对每个节点单独运行所有操作,并让每个操作调用相同的完成函数,该函数必须维护一个标志,以确保只调用一次。 另一种选择是避免使用完成处理程序,并在与动画持续时间匹配

  • 我有一些@keyframes动画和相关的CSS类名。例如,类似于: 如果我显示多个应用了.fade类的元素,有没有办法将它们锁定在一起,使它们在动画关键帧中共享相同的位置? 例如,如果我从一个开始,并且碰巧在第一个在动画中达到50%时添加了第二个,那么我希望第二个从50%开始,这样所有内容都会一起淡入淡出。

  • 我在为我的React本机应用程序设置testID和accessibilityLabel时遇到了一个奇怪的问题,其目的是让Appium Inspector(Appium Desktop)可以看到iOS和Android应用程序上的“accessibility id”,问题如下: 如果testID是设置在一起的辅助标签,iOS的应用程序不显示"辅助ID"的组件,但android的应用程序。 如果我只设置

  • 问题内容: 因此,基本上在我的游戏中,我需要抛掷或扔出一个物体。到目前为止,我有一个精灵,可以拖动它,但是不能抛出它。游戏的想法是扔一个精灵与另一个精灵碰撞。我想要一个我们称之为testNode的精灵,以移动用户将其扔到何处 意思是,当我释放精灵时,我希望它沿我移动它的方向继续。我花了很长时间尝试解决这个问题,但我做不到。我正在使用SpriteKit for iOS 8+。如果有人可以帮忙,请做。

  • 我有Tomcat(7或8),有两个虚拟主机和两个应用程序克隆,应该可以工作。 每个应用程序都应该有自己的配置文件。它不应该放在*. war中——只能放在服务器环境中的某个地方。 当我在Tomcat中有一个应用程序时,我可以将配置文件放在 这是Spring根据applicationContext查找我的配置文件的方式。xml。 但是当我有两台主机时,我应该将配置文件放在不同的目录中。我在服务器的主机

  • 我有一个场景,有4个不同的API调用,它们总是保持不变。我试图创建一个并行的压力测试,我希望相同的场景首先运行,比如10%,然后是20%,30%······max用户的等等。 但我也需要设置是动态的,取决于脚本中的可配置变量这是造成问题的原因,我希望能够很容易地配置它运行例如10%,50%和100%。 这就是我到目前为止所做的(缩短了,并且onceuser和nothingFor从迭代于bla(I)