我正在尝试使用CADisplayLink
为游戏循环获得恒定的帧频。在模拟器中测试时,我无法达到稳定的时间范围。我应该考虑其他方法吗?
还是仅仅是因为模拟器无法正确模拟硬件?
根据Apple,这是计算FPS的方法:
let actualFramesPerSecond = 1 / (displaylink.targetTimestamp - displaylink.timestamp)
在我设置用于测试的普通iOS应用程序中,它会打印出恒定的帧频:
FPS: 59.99999875668439
FPS: 59.99999875668439
FPS: 59.99999875668439
FPS: 59.99999875668439
FPS: 59.99999875668439
但是,当我使用实际经过的时间来计算FPS时,它会给出其他信息:
FPS: 64.35942918520792
FPS: 58.30848150362142
FPS: 57.640194044003465
FPS: 64.47022656706324
FPS: 59.392580005664115
FPS: 60.282043174566674
另外,在使用代码渲染某些图片时,它在模拟器中看起来不稳定。上面的代码片段怎么可能与现实相去甚远?
我主要关心的是:为什么以Apple方式计算FPS时帧速率恒定?他们的文档是否可能仅包含一些小故障?此外,在有一些负载的情况下,“实际”值是可以预期的,但是对于空循环却什么也不做呢?
这是我用来执行游戏循环的代码:
private var previousTimeInSeconds: Double = 0
private lazy var displayLink: CADisplayLink = {
let displayLink = CADisplayLink(target: self,
selector: #selector(displayLoop))
return displayLink;
}()
private func startLoop() {
previousTimeInSeconds = Date().timeIntervalSince1970
displayLink.add(to: .current, forMode: .common)
}
@objc private func displayLoop() {
let currentTimeInSeconds = Date().timeIntervalSince1970
let elapsedTimeInSeconds = currentTimeInSeconds - previousTimeInSeconds
previousTimeInSeconds = currentTimeInSeconds
//let actualFramesPerSecond = 1 / (displayLink.targetTimestamp - displayLink.timestamp) // is showing constant 59.xxx FPS
let actualFramesPerSecond = 1 / elapsedTimeInSeconds
print("FPS: \(actualFramesPerSecond)") // varies from 50.xxx to 70.xxx FPS
/*
FPS: 64.35942918520792
FPS: 58.30848150362142
FPS: 57.640194044003465
FPS: 64.47022656706324
FPS: 59.392580005664115
FPS: 60.282043174566674
*/
}
最佳答案
我想我找到了答案。不要使用Date().timeIntervalSince1970
计算每秒的单个帧速率。似乎还不够精确。
而是使用displayLink.timestamp
,它是与最后显示的帧关联的时间值。将我上面代码中的Date()
用法替换为timestamp
,您将获得预期的FPS值:
FPS: 59.99999875668439
FPS: 59.99999896623196
FPS: 59.99999875668439
FPS: 59.99999875668439
FPS: 59.99999875668439
FPS: 29.999999430729087
FPS: 59.99999875668439
FPS: 59.99999875668439
FPS: 59.99999875668439
FPS: 59.99999875668439
FPS: 59.99999896623196
FPS: 59.99999875668439
FPS: 59.99999875668439
FPS: 59.99999875668439
FPS: 59.99999896623196
如您所见,它基本上保持在59 FPS不变,这里和那里都有几滴下降,这是完全可以预期的,因为不能保证以恒定的速率调用
CADisplayLink
。但是在“劳动状况”下,几乎没有代码可以执行,这就是您期望的帧速率。如果要计算实际帧速率时间,我从Apple文档中获取的公式(“ letactualFramesPerSecond = 1 /(displayLink.targetTimestamp-displayLink.timestamp)”)是没有用的。相反,它表明
targetTimestamp
可用于实现稳定的游戏循环(因为结果值确实是常数)。我希望有关文件的内容可以更加清楚。关于ios - CADisplayLink无法在模拟器中获得恒定的帧速率,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57937529/