我一直在寻找一种解决方案,以便在用户“按下 Tab 键”游戏时暂停我的 SpriteKit 游戏。到目前为止,我找到了一个解决方案,您可以使用 SKAction
而不是 NSTimer
,只要操作之间的时间保持不变,这个解决方案就有效。但是,我的 NSTimer
的速度发生了变化。所以我需要寻找另一个解决方案。
我有一堆 NSTimer
位于 GameScene -> didMoveToView
NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector: Selector("SpawnBullets"), userInfo: nil, repeats: true)
NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("SpawnMeteors"), userInfo: nil, repeats: true)
NSTimer.scheduledTimerWithTimeInterval(timeInterval, target: self, selector: Selector("onTimer:"), userInfo: nil, repeats: true)
现在,当应用程序进入后台时,我如何简单地暂停它们?
编辑:添加了我的时间间隔增加速度功能
func onTimer(timer: NSTimer) {
var goodTimes = time / 20
if (goodTimes > 1.8){
goodTimes = 1.8
}
timer.fireDate = timer.fireDate.dateByAddingTimeInterval(timeInterval - goodTimes)
self.runAction(SKAction.sequence([SKAction.runBlock(SpawnRocks), SKAction.waitForDuration(goodTimes / 2), SKAction.runBlock(SpawnPowerUp)]))
}
最佳答案
NSTimer
的暂停不是 Objective-C 或 swift 的原生功能。为了解决这个问题,您需要创建一个扩展,我碰巧已经创建了该扩展并将与您分享。这适用于 OS X 和 iOS
import Foundation
import ObjectiveC
#if os(iOS)
import UIKit
#else
import AppKit
#endif
private var pauseStartKey:UInt8 = 0;
private var previousFireDateKey:UInt8 = 0;
extension NSTimer
{
private var pauseStart: NSDate!{
get{
return objc_getAssociatedObject(self, &pauseStartKey) as? NSDate;
}
set(newValue)
{
objc_setAssociatedObject(self, &pauseStartKey,newValue,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN);
}
}
private var previousFireDate: NSDate!{
get{
return objc_getAssociatedObject(self, &previousFireDateKey) as? NSDate;
}
set(newValue)
{
objc_setAssociatedObject(self, &previousFireDateKey,newValue,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN);
}
}
func pause()
{
pauseStart = NSDate();
previousFireDate = self.fireDate;
self.fireDate = NSDate.distantFuture() ;
}
func resume()
{
if(pauseStart != nil)
{
let pauseTime = -1 * pauseStart.timeIntervalSinceNow;
let date = NSDate(timeInterval:pauseTime, sinceDate:previousFireDate );
self.fireDate = date;
}
}
}
然后,当您需要使用它时,只需调用 timer.pause()
和 timer.resume()
您当然必须在您的gamescene 对象来执行此操作,因此请确保 timer
是整个类都可以访问的变量,并且在创建计时器时,您需要 timer = NSTimer.schedule...
类(class)开始时:
var spawnBulletsTimer : NSTimer?;
var spawnMeteorsTimer : NSTimer?;
var onTimer: NSTimer?;
创建计时器时:
spawnBulletsTimer = NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector: Selector("SpawnBullets"), userInfo: nil, repeats: true)
spawnMeteorsTimer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("SpawnMeteors"), userInfo: nil, repeats: true)
onTimer = NSTimer.scheduledTimerWithTimeInterval(timeInterval, target: self, selector: Selector("onTimer:"), userInfo: nil, repeats: true)
然后当你需要暂停时:
onTimer?.pause()
spawnBulletsTimer?.pause()
spawnMeteorTimer?.pause()
然后当您需要恢复时:
onTimer?.resume()
spawnBulletsTimer?.resume()
spawnMeteorTimer?.resume()
关于swift - 按 home 按钮时暂停 NSTimer,并在应用程序位于前台后再次启动它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34383852/