本文介绍了在主页按钮按下时暂停 NSTimer 并在应用程序处于前台后再次启动它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找一种解决方案来在用户按下"游戏时暂停我的 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 并在应用程序处于前台后再次启动它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 03:19