问题:SKScene
中的update(currentTime:)
函数在每一帧都用一个currentTime
参数调用。我想知道如何在不使用update
函数的情况下从update(currentTime:)
使用的同一来源获取时间。我只发现了CFAbsoluteTimeGetCurrent()
不同。
原因:要计算timeSinceLastUpdate
,您需要一个名为 timeOfLastUpdate
的实例变量。要实现timeOfLastUpdate
您需要在第一次更新之前将其设置为任意值,这使得timeSinceLastUpdate
的第一次计算不正确。你可以有一个简单的 if 语句来检测这一点或使用可选,但这是一个不需要的分支,如果我只是在 didMoveToView(view:)
中设置timeOfLastUpdate
就可以避免。这就是我要做的。
第一个timeSinceLastUpdate
将始终与其他不同。 通常,从上一个update
调用中存储绝对时间,并从当前调用的时间中减去它以获得timeSinceLastUpdate
。 如果上一个时间不存在,因为你是第一次通过渲染循环——它被设置为零或无穷大或负数或你初始化的任何哨兵值,只需将你的timeSinceLastUpdate
设置为某个标称值即可开始。 像你的帧间隔(如果你要达到 60 fps,则为 16.67 毫秒)是有意义的——你不希望依赖于该时间间隔的游戏代码做一些疯狂的事情,因为你传递了它零或一些非常巨大的价值。
事实上,有逻辑将你的timeSinceLastUpdate
规范化为理智的东西并不是一个坏主意,以防它变得很大——比如,因为你的用户暂停并恢复了游戏。如果您有游戏实体(例如 GameplayKit 代理),其移动遵循某种position += velocity * timeSinceLastUpdate
模型,则您希望它们在您从暂停恢复时移动一帧的时间,而不是采取五分钟的暂停乘以速度并跳转到超空间。
如果将上一个时间初始化为零、减去并规范化为预期的帧间隔,则将使用相同的代码涵盖开始和取消暂停情况。
您可以随时使用合并:
let deltaTime = currentTime - (previousTime ?? currentTime).
在第一次循环中,您的 deltaTime 为 0(应该是这个),之后,它是更改
当然,上一个时间必须是可选的,才能正常工作