swift - ios8 Swift SpriteKit - 快速暂停和恢复 NSTimers

标签 swift timer ios8 nstimer invalidation

我在网上搜索了很多次,但没有找到这个问题的答案。我知道如何使用 invalidate 函数——timer.invalidate 来暂停和恢复 NSTimers。我知道如何恢复它们。但我有一个 SpriteKit 游戏。当我暂停游戏时,我会停止一切和计时器。我知道我可以使用 .invalidate 来阻止它们,但是当我使它们无效时:

例如,假设我有一个连续运行的 5 秒计时器,会生成一个方 block 。

当计时器到达周期的第 3 秒并且当我暂停游戏时,并使计时器无效。当我恢复时,现在计时器秒数回到 0,我必须再等待 5 秒。我希望它从中断处继续, 3 ,并等待 2 秒以生成 block 。

            blockGenerator.generationTimer?.invalidate()

            self.isGamePaused = true
            self.addChild(self.pauseText)

            self.runAction(SKAction.runBlock(self.pauseGame))

e`

当我恢复它时:

blockGenerator.generationTimer = ...

我还得再等 5 秒,我希望计时器从上次停止的地方继续

如果您能帮助我,我将不胜感激,谢谢。

最佳答案

有一种方法可以暂停/恢复 Timer 实例,因为使用重复计时器我们知道下一个触发日期

这是一个简单的类SRTimer和一个协议(protocol)SRTimerDelegate


协议(protocol)SRTimerDelegate

protocol SRTimerDelegate : AnyObject {
    func timerWillStart(_ timer : SRTimer)
    func timerDidFire(_ timer : SRTimer)
    func timerDidPause(_ timer : SRTimer)
    func timerWillResume(_ timer : SRTimer)
    func timerDidStop(_ timer : SRTimer)
}

SRTimer 类

class SRTimer : NSObject {
    
    var timer : Timer?
    var interval : TimeInterval
    var difference : TimeInterval = 0.0
    var delegate : SRTimerDelegate?
    
    init(interval: TimeInterval, delegate: SRTimerDelegate?)
    {
        self.interval = interval
        self.delegate = delegate
    }

    @objc func start(_ aTimer : Timer?)
    {
        if aTimer != nil { fire(self) }
        if timer == nil {
            delegate?.timerWillStart(self)
            timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(fire), userInfo: nil, repeats: true)
        }
    }

    func pause()
    {
        if timer != nil {
            difference = timer!.fireDate.timeIntervalSince(Date())
            timer!.invalidate()
            timer = nil
            delegate?.timerDidPause(self)
        }
    }

    func resume()
    {
        if timer == nil {
            delegate?.timerWillResume(self)
            if difference == 0.0 {
                start(nil)
            } else {
                Timer.scheduledTimer(timeInterval: difference, target: self, selector: #selector(start), userInfo: nil, repeats: false)
                difference = 0.0
            }
        }
    }

    func stop()
    {
        if timer != nil {
            difference = 0.0
            timer!.invalidate()
            timer = nil
            delegate?.timerDidStop(self)
        }
    }
    
    @objc func fire(_ sender : SRTimer)
    {
        delegate?.timerDidFire(self)
    }

}

使您的类符合协议(protocol) SRTimerDelegate 并使用以下命令初始化 SRTimer 实例

var timer : SRTimer!
timer = SRTimer(interval: 5.0, delegate: self)

方法

start() 调用委托(delegate)方法 timerWillStart 并启动计时器。

pause() 保存当前日期和下一个触发日期之间的差异,使计时器无效并调用委托(delegate)方法 timerDidPause

resume() 调用委托(delegate)方法timerWillResume,使用保存的差异时间间隔创建一个临时一次性计时器。当此计时器触发时,主计时器将重新启动。

stop() 调用委托(delegate)方法 timerDidStop 并使计时器无效。

当计时器触发时,将调用委托(delegate)方法timerDidFire

关于swift - ios8 Swift SpriteKit - 快速暂停和恢复 NSTimers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31933213/

相关文章:

arrays - 使用 Swift 查询 friend 的 friend

javascript - 使用计时器以给定的时间间隔打印数组的各个元素

ios - 在 swift 中为 View 创建 IBOutlet 时,基类附加了一个?

ios - 新的 iTunes 连接界面——是否应该立即在 "Prerelease"上看到它?

timer - 安排一个函数每小时整点运行

ios - 许多 CGContext 无效上下文 0x0 错误 iOS 8

ios - 我想将 FCMToken 发送到 IOS 中的 URL

ios - 在 Swift 中使用以编程方式创建的 UITableViewCell 子类

ios - 使文本字段多行 - SwiftUI

swift - 通过 Action 使 SKPhysicsBody 充满活力