SKAction持续时间如何与帧速率相关?

时间:2014-12-14 02:30:34

标签: ios swift sprite-kit skaction

我想了解SKActions的工作原理。特别是SKAction.runAction(),其中一个参数是动画的持续时间。然而,似乎无论我把它作为持续时间,动画都将渲染每一帧。我试图将SKAction.runAction()行放在其他位置,但它似乎只适用于update()中的SKScene覆盖方法。我已经尝试了SKAction.repeatActionForever,但这似乎无法与其他进程并行运行。

我的问题是,如果在动画的持续时间内有一个必需的参数,那么将SKAction.runAction()方法放置在哪里让动画根据给定的持续时间而不是帧速率运行?

这是我的代码:

GameScene.swift(Player类是Character类的子类。请参阅下面的代码。)

let player = Player()
class GameScene: SKScene {
   override func didMoveToView(view: SKView) {
      //Code here to recognize user inputs
      scene?.addChild(player.sprite)
   }

   override func update(currentTime: CFTimeInterval) {
      player.sprite.runAction(SKAction.runBlock(player.move))
   }
}

CharachterClass.swift move()函数

func move(){
   switch(direction){
      case "up":
         sprite.position = CGPoint(x: sprite.position.x, y: sprite.position.y + speed)
      case "down":
         sprite.position = CGPoint(x: sprite.position.x, y: sprite.position.y - speed)
      case "right":
         sprite.position = CGPoint(x: sprite.position.x + speed, y: sprite.position.y)
      case "left":
         sprite.position = CGPoint(x: sprite.position.x - speed, y: sprite.position.y)
      default:
         break
    }
    SKAction.moveTo(sprite.position, duration: 1)
}

注意:direction变量是精灵移动的方向,speed变量是精灵每次运行SKAction时应移动的像素数。

1 个答案:

答案 0 :(得分:2)

我不知道你打算怎么做:

override func update(currentTime: CFTimeInterval) {
   player.sprite.runAction(SKAction.runBlock(player.move))
}

但实际上你可以简单地做以下事情:

override func update(currentTime: CFTimeInterval) {
   player.move()
}

两种方法之间的区别在于runAction将调度块执行,并且根据调度发生的时间,它可能不会在当前帧(更新周期​​)中运行,而是在下一帧中运行。因此,运行块解决方案很可能会引入1帧延迟。

接下来,这将持续1秒的移动动作(不: 1帧):

SKAction.moveTo(sprite.position, duration: 1)

由于您在每个更新方法中运行此操作,因此您实际上无效和无效SKAction的主要目的:在给定时间内运行任务(持续时间)。

更糟糕的是,您每帧都会运行一个新的移动操作,因此在1秒的持续时间内,您可能会累积大约60个同时运行的移动操作,并且具有未定义的行为。

如果你使用“key”参数调用runAction,你至少可以阻止堆叠操作,但它仍然是毫无意义的,因为每1帧时间内应该运行的每一帧替换一个动作意味着它会产生很小的影响,如果有的话。

巧合的是,对于现在设置代码的方式,你也可以直接分配到位置......但是......等等,你已经这样做了:

sprite.position = CGPoint(x: sprite.position.x - speed, y: sprite.position.y)

但是之后立即执行此移动操作:

SKAction.moveTo(sprite.position, duration: 1)

总而言之,你尝试在1秒的时间内完成一个动作,最终每帧都被替换(每秒60次) - 而这个动作确实......没有。它不会做任何事情,因为你已经将精灵设置在你随后作为所需目标位置传递到移动动作的位置。但精灵已经处于那个位置,让行动无关紧要。一秒钟 - 或者它可能会提早退出,这取决于我们不了解的SK实施细节。

无论你怎么看,这个移动动作都是过度设计的没有效果。我建议你(重新)阅读actions article in the SK Programming Guide以更好地理解时间和其他行为行为。