问题描述
我一直在寻找一种解决方案来在用户按下"游戏时暂停我的 SpriteKit 游戏.到目前为止,我找到了一个使用 SKAction
代替 NSTimer
的解决方案,只要操作之间的时间保持不变,就可以使用.但是,我的 NSTimer
的速度发生了变化.所以我需要找到另一个解决方案.
I've been searching for a solution to pause my SpriteKit game when the user "tabs down" the game. So far I found a solution where you use SKAction
's instead of NSTimer
's, this works as long as the time between actions stays the same. However, my NSTimer
's changes in speed. So I need to find another solution.
我有一堆 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)
现在,当应用进入后台时,我如何简单地暂停它们?
Now, how would I simply pause them when the app enters background?
添加了我的时间间隔增加速度功能
Added my timeInterval increase-speed-function
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
Pausing of NSTimer
is not a native feature in objective-c or swift. To combat this, you need to create an extension, which I happen to have created and will share for you. This will work for both OS X and 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...
Then when you need to use it, simply call timer.pause()
and timer.resume()
You of course have to keep track of your timers in your gamescene object to do this, so make sure that timer
is a variable accessible for the entire class, and when making your timer, you do timer = NSTimer.schedule...
在课程开始时:
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()
这篇关于在主页按钮按下时暂停 NSTimer 并在应用程序处于前台后再次启动它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!