To set up a game loop in Objective-C I learnt that I should set up a CADisplayLink
为了在Objective-C中建立一个游戏循环,我知道我应该建立一个CADisplayLink
updater = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLoop) ];
[updater setFrameInterval: 1];
[updater addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSRunLoopCommonModes];
How do I do this in Swift?
我怎么才能做到这一点呢?
I have tried to Google this but I cannot find any examples of this.
我试过这个但找不到任何例子。
3 个解决方案
#1
24
Pretty much just a direct translation from Objective-C to Swift with a few tweaks.
这只是从Objective-C到Swift的直接翻译。
import QuartzCore
var updater = CADisplayLink(target: self, selector: Selector("gameLoop"))
updater.frameInterval = 1
updater.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
#2
6
Swift 3.x version of Brian Tracy's answer:
斯威夫特3。布莱恩·特雷西的回答有x种版本:
let updater = CADisplayLink(target: self, selector: #selector(self.gameLoop))
updater.preferredFramesPerSecond = 60
updater.add(to: RunLoop.current, forMode: RunLoopMode.commonModes)
Apart from the syntax changes of Swift 3, also note the iOS 10 API change from frameInterval
(which still works, but produces a deprecated warning) to preferredFramesPerSecond
.
除了Swift 3的语法更改外,还要注意iOS 10 API从frameInterval(仍然有效,但产生了一个不赞成的警告)更改为preferredFramesPerSecond。
#3
5
Here's my GameLoop
class (Swift 3)
这是我的游戏类(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
}
}
If you're updating something on a background GCD queue and want to pull those changes to the Main queue (and runloop), you should use Dispatch Source for Data.
如果您正在更新后台GCD队列上的某些内容,并希望将这些更改拉到主队列(和runloop),则应该使用Dispatch Source来获取数据。
#1
24
Pretty much just a direct translation from Objective-C to Swift with a few tweaks.
这只是从Objective-C到Swift的直接翻译。
import QuartzCore
var updater = CADisplayLink(target: self, selector: Selector("gameLoop"))
updater.frameInterval = 1
updater.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
#2
6
Swift 3.x version of Brian Tracy's answer:
斯威夫特3。布莱恩·特雷西的回答有x种版本:
let updater = CADisplayLink(target: self, selector: #selector(self.gameLoop))
updater.preferredFramesPerSecond = 60
updater.add(to: RunLoop.current, forMode: RunLoopMode.commonModes)
Apart from the syntax changes of Swift 3, also note the iOS 10 API change from frameInterval
(which still works, but produces a deprecated warning) to preferredFramesPerSecond
.
除了Swift 3的语法更改外,还要注意iOS 10 API从frameInterval(仍然有效,但产生了一个不赞成的警告)更改为preferredFramesPerSecond。
#3
5
Here's my GameLoop
class (Swift 3)
这是我的游戏类(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
}
}
If you're updating something on a background GCD queue and want to pull those changes to the Main queue (and runloop), you should use Dispatch Source for Data.
如果您正在更新后台GCD队列上的某些内容,并希望将这些更改拉到主队列(和runloop),则应该使用Dispatch Source来获取数据。