【问题标题】:How do SKAction durations work in relation to frame rates?SKAction 持续时间如何与帧速率相关?
【发布时间】:2015-02-12 11:18:26
【问题描述】:

我正在尝试了解 SKActions 的工作原理。特别是SKAction.runAction(),其中一个参数是动画的持续时间。然而,似乎无论我输入什么持续时间,动画都会渲染每一帧。我曾尝试将SKAction.runAction() 线放在其他地方,但它似乎只适用于SKScene 中的update() 覆盖方法。我试过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 时精灵应该移动的像素数量。

【问题讨论】:

    标签: ios swift sprite-kit skaction


    【解决方案1】:

    我不知道你打算用这个做什么:

    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 以更好地了解时间和其他动作行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 2015-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多