【问题标题】:SKAction Moveto not completing within the duration?SKAction Moveto 没有在持续时间内完成?
【发布时间】:2017-12-14 14:19:56
【问题描述】:

我正在尝试制作类似带有扫手的时钟。

我从NSDate 获取会议记录。

然后稍微计算一个弧度值并找到我的精灵应该在 1 分钟内移动到的 XY 位置,

然后在下一分钟开始时,我会计算我的精灵在该分钟内应该移动到的下一个 XY 位置。

所以我在更新函数中有这些代码

//Get Current Minute
var currentTime = NSDate();
var nowCal = NSCalendar(calendarIdentifier: NSCalendar.Identifier.ISO8601)
var currMin = nowCal?.component(.minute, from: currentTime as Date)

//Print current minute        
print(currMin)

// slicing the circle into 60 segments and getting which angle in radians the sprite should move to in the next min
var minAng = (2*CGFloat.pi)/60 * CGFloat(currMin!)

//calculating point on the circle where the sprite should move to in the next min        
var newPt = CGPoint(x: (300 * cos(minAng)), y: -(300 * sin(minAng)))

//print out where the sprite currently is and where it should move to 
print(hand.position)
print(newPt)


//move the sprite to the new location over 60 seconds, making sure the movement is linear        
let moveHand = SKAction.move(to: newPt, duration: 60)
moveHand.timingMode = SKActionTimingMode.linear
hand.run(moveHand)

//move another placeholder sprite to the final destination instantly to visualise movment by waiting for the moving sprite.
handToBe.run(SKAction.move(to: newPt, duration: 0))

假设我正确理解所有内容,它应该在 1 分钟内通过该段,在需要移动到下一个段之前到达该段的末尾。

但是,我的精灵在需要移动到下一个片段之前从未到达片段的末尾。打印输出显示它总是太慢。

我对@9​​87654323@ 有什么不明白的地方,还是我的逻辑在这种情况下有缺陷?

【问题讨论】:

  • 你为什么不直接使用 rotateTo 动作?
  • 我没有旋转。它是一个必须在圆形路径上移动的精灵。我想我可以让它成为一个非常大的透明精灵,一端有一个点,但是会有两个问题。我无法旋转精灵并将其移动一圈,而且很难缩放。另外,重点是我试图将 Moveto 中的持续时间问题理解为一个学习实验,而不是试图找到替代方法。但是我怀疑按持续时间轮换到的行为可能类似。
  • 是的,这将是相同的行为
  • @Eivie update: 方法中的操作使用错误。如果update: 方法每秒调用 60 次(理想情况下),那么运行持续时间为 60 秒(甚至 1 秒)的动作有什么意义?我的意思是没有if 语句,所以我假设这段代码无论如何都会运行。
  • @Whirlwind 我正在使用更新方法,就像在游戏设计中一样。这不是更新的目的吗?我希望持续 1/60 秒的动作将在下一帧开始时结束,并为其提供下 1/60 秒的动作。

标签: ios swift sprite-kit skaction


【解决方案1】:

尝试从update 函数中删除代码,然后在您自己调用的函数中运行它。 update 每帧都被调用,所以精灵开始移动,然后下一帧它被告知移动到另一个位置,所以它现在有两个需要同时运行的移动动作。之后的帧有 3 个需要运行的移动动作,等等。这可能意味着它永远不会真正到达它的第一个预期位置,因为同时影响它的其他移动动作。

【讨论】:

  • 嗯,我明白你的意思了。但这是否意味着我要求运行 1/60 秒的动作并没有在以 60 fps 持续 1/60 秒的帧中完成?我可以从更新函数中删除代码并尝试永远使用重复,但这意味着实现路径。我对此犹豫不决,因为这听起来可能会使代码复杂化,而且我也不确定它是否能提供我所追求的发条精度。
  • 是的,动作没有在帧中完成,因为动作的持续时间被设置为 60 秒。我不知道是否有必要实施该路径。您可以在第一个移动操作完成后运行下一个移动操作,例如 run(someAction, completion: { callTheActionAgain() } )
  • 我不知道有这样的功能。我也会探讨这个选项。实际上,当我说我将它设置为运行 1/60 秒时,我错了我重新阅读了我的代码,实际上,我要求动作在 60 秒内到达该点,每秒 60 次。这会引起问题吗?
  • 我认为这是代码未按预期运行的主要原因,即操作设置为持续 60 秒。我仍然会避免将代码放在更新函数中,因为如果帧速率下降,您将失去 1/60 秒的精度(例如,更新函数不是每秒调用 60 次,而是每秒调用 50 次,这意味着移动动作在 1 秒内只会执行 50 次)。取而代之的是,可能会考虑执行 1/60 秒的操作,然后在完成后调用下一个操作。希望这会有所帮助!
猜你喜欢
  • 2015-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-11
  • 2019-07-20
  • 2014-03-23
  • 1970-01-01
相关资源
最近更新 更多