我正在尝试使用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/

10-13 06:34