Ios 为什么我的SpriteKit update()函数会创建多个NSTimer?

Ios 为什么我的SpriteKit update()函数会创建多个NSTimer?,ios,swift,sprite-kit,Ios,Swift,Sprite Kit,我正在创建一个SpriteKit游戏,它会根据经过的时间进行更新。游戏使用NSTimer及其scheduledTimerWithTimeInterval方法生成敌人,每2.0秒调用spawnktown函数 当5秒过去,应该有一个非常短暂的间歇,防止新的敌人产卵,以显示一个级别变化动画 当达到最初的5秒时,一切正常,直到条件whereself.nextLevelDelayTicker==100。满足此条件后,“YOLO”字符串在控制台中仅触发一次。但是,我假设在self.timer中创建并存储了多

我正在创建一个SpriteKit游戏,它会根据经过的时间进行更新。游戏使用
NSTimer
及其
scheduledTimerWithTimeInterval
方法生成敌人,每2.0秒调用
spawnktown
函数

当5秒过去,应该有一个非常短暂的间歇,防止新的敌人产卵,以显示一个级别变化动画

当达到最初的5秒时,一切正常,直到条件where
self.nextLevelDelayTicker==100
。满足此条件后,
“YOLO”
字符串在控制台中仅触发一次。但是,我假设在
self.timer
中创建并存储了多个
NSTimer
实例,因为在调用
self.resumeGame()
创建新的定时后会产生大量敌人

尽管我在条件中设置了只调用一次
self.resumeGame()
函数的标志,但您知道为什么会发生这种情况吗

func resumeGame() {
    // Start game timer
    // Need a way to access ib action of pause button
    self.timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "spawnEnemy", userInfo: nil, repeats: true)
}

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
    if gameTicker.isActive == true {
        gameTicker.increment()
    }

    // If gameTicker is equal to 5 seconds, increase enemy amount
    if gameTicker.getTimePassed() % 500 == 0 {
        self.enemyAmount += 1
        self.timer?.invalidate()
        levelCount += 1

        gameTicker.isActive = false
    }

    // If level has been completed and last ghost has been killed, activate next level scene
    if gameTicker.isActive == false && enemyArray.count == 0 {
        self.nextLevelDelayTicker.increment()

        if self.nextLevelDelayTicker.getTimePassed() == 100 {
            print("YOLO")
            self.gameTicker.isActive = true
            self.nextLevelDelayTicker.reset()
            self.resumeGame()
        }
    }
}

正在尝试遵循您的代码。。但我认为你的方法对spritekit来说不是很好。这可能使事情变得比需要的更复杂

您可以直接使用更新方法跟踪时间。可能值得重写代码的这一部分。在spritekit中工作得更好,更不容易出现bug

你真正需要的是三角洲时间

场景属性

// time values
var delta = NSTimeInterval(0)
var last_update_time = NSTimeInterval(0)

// some time youre trying to keep track of
var timeLimit = NSTimeInterval(5)
var timeLimitMax = NSTimeInterval(5)
场景的更新方法

 func update(currentTime: NSTimeInterval) {
        if last_update_time == 0.0 {
            delta = 0
        } else {
            delta = currentTime - last_update_time
        }

        last_update_date = currentTime

        // now we can keep track of time
        timeLimit -= self.delta
        if timeLimit <= 0 {
            // do something and reset timer
            timeLimit = timeLimitMax
        }
}

正在尝试遵循您的代码。。但我认为你的方法对spritekit来说不是很好。这可能使事情变得比需要的更复杂

您可以直接使用更新方法跟踪时间。可能值得重写代码的这一部分。在spritekit中工作得更好,更不容易出现bug

你真正需要的是三角洲时间

场景属性

// time values
var delta = NSTimeInterval(0)
var last_update_time = NSTimeInterval(0)

// some time youre trying to keep track of
var timeLimit = NSTimeInterval(5)
var timeLimitMax = NSTimeInterval(5)
场景的更新方法

 func update(currentTime: NSTimeInterval) {
        if last_update_time == 0.0 {
            delta = 0
        } else {
            delta = currentTime - last_update_time
        }

        last_update_date = currentTime

        // now we can keep track of time
        timeLimit -= self.delta
        if timeLimit <= 0 {
            // do something and reset timer
            timeLimit = timeLimitMax
        }
}

我对你的答案投了更高的票,因为这是SpriteKit中的方法,但是你应该稍微改变一下动作。首先,您需要在块内部显式地进行self编译。其次,它将创建强引用循环,场景在过渡到下一个场景后将永远不会被释放,因为自我被捕获,动作是无止境的。因此,在转换之前,要么显式删除操作,要么在块(无主自)中使用捕获列表,都可以解决问题。好的观点。。我在没有xcode的情况下编写了这段代码,所以我确信它不是100%完美的。我会编辑。关于基于计时器的繁殖敌人,这是一个很好的答案。我扔掉了所有的
NSTimer
s,取而代之的是一个SKAction。暂停/恢复功能现在起作用了。不过有一件事,我需要能够每15秒暂停一次
spawnAction
SKAction,持续5秒,以便显示动画并防止敌人在此期间产卵。一旦5秒延迟结束,我需要能够重新激活
SKAction
。是否有暂停
SKAction
方法可用?我是否只需将更多的
SKAction.waitForDuraction(2)
s硬编码到
SKAction.repeatActionForever
,然后在最后添加一个
SKAction.waitForDuraction(5)
?需要注意的是,只有在所有敌人被杀死/从场景中移除后,动画的5秒延迟才会被激活。我读了你写的几次,并没有真正理解你要做的事情。然而,一旦它变得如此复杂,我倾向于开始使用更新和动作。当你做一次性的事情时,Skaction是很棒的。。但一旦设置好,就不能修改它。您只能取消它并创建一个新的。如果涉及到逻辑和不断变化的条件,那么在这一点上使用update可能会更好。我对你的答案投了赞成票,因为在SpriteKit中这是一种方式,但是你应该稍微改变一下操作。首先,您需要在块内部显式地进行self编译。其次,它将创建强引用循环,场景在过渡到下一个场景后将永远不会被释放,因为自我被捕获,动作是无止境的。因此,在转换之前,要么显式删除操作,要么在块(无主自)中使用捕获列表,都可以解决问题。好的观点。。我在没有xcode的情况下编写了这段代码,所以我确信它不是100%完美的。我会编辑。关于基于计时器的繁殖敌人,这是一个很好的答案。我扔掉了所有的
NSTimer
s,取而代之的是一个SKAction。暂停/恢复功能现在起作用了。不过有一件事,我需要能够每15秒暂停一次
spawnAction
SKAction,持续5秒,以便显示动画并防止敌人在此期间产卵。一旦5秒延迟结束,我需要能够重新激活
SKAction
。是否有暂停
SKAction
方法可用?我是否只需将更多的
SKAction.waitForDuraction(2)
s硬编码到
SKAction.repeatActionForever
,然后在最后添加一个
SKAction.waitForDuraction(5)
?需要注意的是,只有在所有敌人被杀死/从场景中移除后,动画的5秒延迟才会被激活。我读了你写的几次,并没有真正理解你要做的事情。然而,一旦它变得如此复杂,我倾向于开始使用更新和动作。当你做一次性的事情时,Skaction是很棒的。。但一旦设置好,就不能修改它。您只能取消它并创建一个新的。如果涉及到逻辑和不断变化的条件,那么在这一点上使用update可能会更好,下面的答案值得考虑,但就您的问题而言,您可以