【问题标题】:Why is runAction() function being called multiple times within my update() method?为什么在我的 update() 方法中多次调用 runAction() 函数?
【发布时间】:2025-12-27 06:35:16
【问题描述】:

在我的 Sprite Kit 中的 func update(currentTime: CFTimeInterval) 方法中,我有一个 gameTicker,每次更新游戏时都会增加一个整数。

gameTicker 可以被 500 整除时,我暂停代码,通过删除在didMoveToView() 中调用的原始操作来禁止敌人生成,然后启动一个用作短暂延迟的nextLevelDelayTicker。一旦nextLevelDelayTicker 达到100,我开始再次增加原始gameTicker,将nextLevelDelayTicker 重置为0,然后运行一个动作以再次开始生成敌人。

基本上,一旦nextLevelDelayTicker 等于100,我只想运行一次条件的内容。我在其中添加了一个print("yolo"),以查看它是否仅在满足条件时才被调用一次,确实如此。但是,由于某种原因,runAction(spawnAction, withKey: "spawnAction") 被多次调用。只要满足self.nextLevelDelayTicker.getTimePassed() == 100的条件,就会在很短的时间内产生大量的敌人。

runAction(spawnAction, withKey: "spawnAction") 怎么被调用多次,而print("yolo") 只被调用一次?

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.removeActionForKey("spawnAction")

        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()

            let spawnAction = SKAction.repeatActionForever(
                SKAction.sequence([
                    SKAction.waitForDuration(2),
                    SKAction.runBlock({
                        [unowned self] in
                        self.spawnEnemy()
                        })
                    ])
            )

            runAction(spawnAction, withKey: "spawnAction")
        }
    }
}

【问题讨论】:

    标签: swift sprite-kit


    【解决方案1】:

    原来我是渡渡鸟头。 runAction(spawnAction, withKey: "spawnAction") 没有被多次调用,它是:

    if gameTicker.getTimePassed() % 500 == 0 {
         self.enemyAmount += 1
         self.removeActionForKey("spawnAction")
    
        gameTicker.isActive = false
    }
    

    被多次调用,将大量敌人添加到 self.enemyAmount 全局变量中,该变量用于确定运行 spawnAction 时生成的敌人数量。

    我在条件中添加了一个标志,与每个游戏周期约 300 次相比,每个关卡周期只调用一次:

    if gameTicker.getTimePassed() % 500 == 0 && gameTicker.isActive == true{
        self.enemyAmount += 1
        self.removeActionForKey("spawnAction")
    
        gameTicker.isActive = false
        print("STOP SPAWNING")
    }
    

    【讨论】: