Я пытаюсь использовать 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
Кроме того, при использовании кода для рендеринга некоторых спрайтов он выглядит нестабильным в симуляторе. Как возможно, что приведенный выше фрагмент кода так сильно расходится с реальностью?
Меня больше всего беспокоит: почему при расчете FPS в Apple используется постоянная частота кадров? Возможно ли, что их документация просто содержит небольшой сбой? Кроме того, «фактические» значения как бы ожидаются, когда есть некоторая нагрузка, но для пустого цикла, который ничего не делает?
Это код, который я использую для выполнения своего игрового цикла:
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
*/
}