如何在Swift中设置游戏循环

mat*_*ats 14 ios swift

要在Objective-C中设置游戏循环,我了解到我应该设置一个CADisplayLink

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

我如何在Swift中执行此操作?

我试过谷歌这个,但我找不到任何这方面的例子.

Bri*_*acy 24

几乎只是从Objective-C到Swift的直接翻译,只需进行一些调整.

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

  • 随机说明:在其上有选择器的Swift类必须扩展`NSObject`. (3认同)

Nik*_*iev 7

Swift 3.x版本的Brian Tracy 回答:

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

除了Swift 3的语法更改之外,还要注意iOS 10 API的更改frameInterval(仍然有效,但会产生不推荐的警告)preferredFramesPerSecond.


Dan*_*ark 5

这是我的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
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您在后台GCD队列上更新某些内容并希望将这些更改提取到主队列(和runloop),则应使用Dispatch Source for Data.