Подтвердить что ты не робот

Как настроить игровой цикл в Swift

Чтобы настроить игровой цикл в Objective-C, я узнал, что должен настроить CADisplayLink

updater = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLoop) ];
[updater setFrameInterval: 1];
[updater addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSRunLoopCommonModes];

Как это сделать в Swift?

Я попытался Google, но я не могу найти никаких примеров этого.

4b9b3361

Ответ 1

Довольно просто прямой перевод из Objective-C в Swift с несколькими настройками.

import QuartzCore
var updater = CADisplayLink(target: self, selector: Selector("gameLoop"))
updater.frameInterval = 1
updater.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)

Ответ 2

Swift 3.x версия Брайана Трейси answer:

let updater = CADisplayLink(target: self, selector: #selector(self.gameLoop))
updater.preferredFramesPerSecond = 60
updater.add(to: RunLoop.current, forMode: RunLoopMode.commonModes)

Помимо синтаксических изменений Swift 3, обратите внимание также, что изменение API iOS 10 от frameInterval (которое все еще работает, но вызывает устаревшее предупреждение) до preferredFramesPerSecond.

Ответ 3

Здесь мой класс GameLoop (Swift 3)

import UIKit

class GameLoop : NSObject {

    var doSomething: () -> ()!
    var displayLink : CADisplayLink!

    init(doSomething: @escaping () -> ()) {
        self.doSomething = doSomething
        super.init()
        start()
    }

    // you could overwrite this too
    func handleTimer() {
        doSomething()
    }

    func start() {
        displayLink = CADisplayLink(target: self, selector: #selector(handleTimer))
        /*
        * If set to zero, the
        * display link will fire at the native cadence of the display hardware.
        * The display link will make a best-effort attempt at issuing callbacks
        * at the requested rate.
        */
        displayLink.preferredFramesPerSecond = 0
        displayLink.add(to: .main, forMode: .commonModes)
    }

    func stop() {
        displayLink.invalidate()
        displayLink.remove(from: .main, forMode: .commonModes)
        displayLink = nil
    }
}

Если вы обновляете что-то в фоновом режиме GCD и хотите перенести эти изменения в главную очередь (и runloop), вы должны использовать Источник отправки для данных,