【问题标题】:SpriteKit custom action with duration of 0.0 is called twice the first time it is ran持续时间为 0.0 的 SpriteKit 自定义操作在第一次运行时被调用两次
【发布时间】:2014-06-01 23:26:01
【问题描述】:

我不确定这是错误还是我做错了什么,但是当我尝试运行持续时间为 0.0 的自定义操作时,该块会运行两次。例如,如果我将此代码放在场景的 init 方法中,我会得到以下输出:

SKAction *doThis = [SKAction customActionWithDuration:0.0 actionBlock:^(SKNode *node, CGFloat elapsedTime) {
    NSLog(@"DO THIS");
}];
[self runAction:doThis];



2014-03-13 01:41:11.271 Leapfrog[2168:60b] DO THIS
2014-03-13 01:41:11.287 Leapfrog[2168:60b] DO THIS

如果我尝试依次运行两个动作,第一次执行两次,第二次执行一次,如下所示:

SKAction *doThis = [SKAction customActionWithDuration:0.0 actionBlock:^(SKNode *node, CGFloat elapsedTime) {
    NSLog(@"DO THIS");
}];
SKAction *doThat = [SKAction customActionWithDuration:0.0 actionBlock:^(SKNode *node, CGFloat elapsedTime) {
    NSLog(@"DO THAT");
}];
NSArray *actions = [NSArray arrayWithObjects:doThis, doThat, nil];
SKAction *sequence = [SKAction sequence:actions];
[self runAction:sequence];



2014-03-13 01:46:11.910 Leapfrog[2184:60b] DO THIS
2014-03-13 01:46:11.926 Leapfrog[2184:60b] DO THIS
2014-03-13 01:46:11.942 Leapfrog[2184:60b] DO THAT

到目前为止,我想出如何让它正常运行的唯一方法是在开头包含一个虚拟动作:

SKAction *wait = [SKAction waitForDuration:0.0];
SKAction *doThis = [SKAction customActionWithDuration:0.0 actionBlock:^(SKNode *node, CGFloat elapsedTime) {
    NSLog(@"DO THIS");
}];
SKAction *doThat = [SKAction customActionWithDuration:0.0 actionBlock:^(SKNode *node, CGFloat elapsedTime) {
    NSLog(@"DO THAT");
}];
NSArray *actions = [NSArray arrayWithObjects:wait, doThis, doThat, nil];
SKAction *sequence = [SKAction sequence:actions];
[self runAction:sequence];



2014-03-13 01:48:41.946 Leapfrog[2192:60b] DO THIS
2014-03-13 01:48:41.964 Leapfrog[2192:60b] DO THAT

每次我想做这种事情时,我是否都陷入了持续时间为零的等待动作?

【问题讨论】:

  • 听起来像一个错误。 Have you filed it with Apple? 但是,如果您正在寻找立即运行一次块的操作,为什么不直接使用 runBlock: 操作?
  • 我只是写了这个例子来说明问题。如果我做一些更复杂的事情,runBlock: 操作将不起作用,比如我想在多个节点之间重用一个操作并且需要对每个节点的引用作为输入变量。无论如何,我猜会绕过提交错误报告。
  • 我遇到了类似的问题,我的块被调用了 100 次,经过时间为 0,然后突然它被调用,经过时间为 4 秒并开始正常工作。跨度>
  • 我将此作为错误报告提交,Apple 声称已修复它,也许有什么不同?

标签: ios sprite-kit


【解决方案1】:

说明

“cutomActionDuration”以秒为单位,并且该操作一直执行到“1 秒”过去为止。在 '0 和 1' 秒之间有足够的时间来执行动作(例如,一秒有 1000 毫秒)。根据您使用的机器/PC 的速度,您将看到执行多次或一次的操作。

RunBlock 解决方案

'customActionWithDuration' 用于重复操作。如果您想在有“runBlock”操作可用时执行操作。缺点是您不能将节点作为参数传递给块。但是您可以使用其他技巧来克服这个缺点(例如,在运行块之前将节点存储在某个全局变量中。该块将为全局节点执行)。这是示例:

SKAction* blockAction = [SKAction runBlock:^{
        //your actions here 
        [SomeNode.physicsBody  applyImpulse:(10,10)];      

    }];

[SomeNode runAction:blockAction];

使用 cutomActionWithDuration 的解决方案

如果您仍想使用“customActionWithDuration”。我有工作解决

SKAction* applyImpulse =[SKAction customActionWithDuration:0.000001      actionBlock:^(SKNode *node, CGFloat elapsedTime) {
        if(!(elapsedTime>0)){
            //Do your thing here :)
        }

    }];

【讨论】:

    【解决方案2】:

    有时 elapsedTime IF 过滤会导致双重动作。 另一种选择是对节点的某种参数实现 IF。 例如: if (![Node hasActions]) {... 在这种情况下,如果操作已应用并正在处理中,则不会加倍。

    【讨论】:

      猜你喜欢
      • 2021-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多