简体   繁体   English

如何更改等待由 SKScene 运行的 SKAction 持续时间?

[英]How to change wait for duration SKAction ran by an SKScene?

In my SpriteKit project, I have a spawnEnemy method.在我的 SpriteKit 项目中,我有一个spawnEnemy方法。 I want this method to be called over and over again so that enemies continue to spawn throughout the game.我希望这个方法被一遍又一遍地调用,以便敌人在整个游戏中继续产生。

What I did to achieve this is to put the spawnEnemy method in an SKAction runBlock and have my SKScene run that action forever with a delay in between calls (to prevent overloading the app).我所做的就是将spawnEnemy方法放在SKAction runBlock中,并让我的SKScene永远运行该操作,并在调用之间延迟(以防止应用程序过载)。

Below is a snippet of the relevant code:以下是相关代码的片段:

var _spawnSpeedSeconds: Double = 2.0

func startSpawning()
{
   let waitForXSeconds = SKAction.waitForDuration(self._spawnSpeedSeconds)

   let spawn = SKAction.runBlock({ () -> Void in
            self.spawnEnemy()
        })      
   self.runAction(SKAction.repeatActionForever(SKAction.sequence([spawn, waitForXSeconds])), withKey: "spawnEnemy")
}

func spawnEnemy()
{
...
}

Now after a certain time (for example when the player gets 5 points or something), I decrease the _spawnSpeedSeconds to make the enemies spawn more in a shorter amount of time to increase difficulty.现在经过一段时间后(例如当玩家获得 5 分或其他东西时),我会降低 _spawnSpeedSeconds 以使敌人在更短的时间内产生更多以增加难度。

The problem is, even if I decrease my _spawnSpeedSeconds variable, the spawn action's delay being ran by the SKScene is still the same.问题是,即使我减少了我的 _spawnSpeedSeconds 变量,SKScene 运行的生成动作的延迟仍然是相同的。

The only way I can think of resolving this issue is to remove the action, and then re-add the action with a new delay/spawn rate.我能想到的解决此问题的唯一方法是删除该动作,然后以新的延迟/生成率重新添加该动作。 Is there a better way to approach this issue?有没有更好的方法来解决这个问题?

Thanks谢谢

don't use an action in this case. 在这种情况下,请勿使用动作。 They don't really work in a dynamic way. 它们实际上并不是以动态方式工作的。 Once you set them, they're stuck. 一旦设置好它们,它们就会卡住。 just use your update method. 只需使用您的更新方法。

I'll show you how I'm periodically launching missles: 我将向您展示如何定期发射导弹:

first set two timers in your class 首先在课堂上设置两个计时器

var missleTimer:NSTimeInterval = NSTimeInterval(2)
var missleInterval:NSTimeInterval = NSTimeInterval(2)

now in our update method we count down the time and spawn missles 现在,在我们的更新方法中,我们倒计时并生成导弹

// subtract time from our timer
self.missleTimer -= self.delta

// when our timer reaches zero
if self.missleTimer <= 0 {
    // run your spawning code
    self.launchMissle()
    // reset timer
    self.missleTimer = self.missleInterval
} 

this is better than using an action in this case because I can set missleInterval anywhere in my code and the change will always be reflected. 这比在这种情况下使用操作要好,因为我可以在代码中的任何地方设置missleInterval ,并且更改始终会得到反映。

-(void)recursiveMethod
{
    if(shouldSpawnEnemy)
    {
        _spawnSpeedSeconds -= 0.01;
        SKAction *wait = [SKAction waitForDuration: 0.5];
        SKAction *action = [SKAction performSelector:@selector(recursiveMethod) onTarget:self];
        SKAction *sequence = [SKAction sequence:@[wait,action]];
        [self repeatActionForever:sequence];
    }
}

Remember to call the recursiveMethod when you want to start spawning enemies. 要开始生成敌人时,请记住调用recursiveMethod。 Hope that helps. 希望能有所帮助。

Providing swift solution without the need for timers, using recursion with a circuit breaker flag:提供 swift 解决方案,无需计时器,使用带有断路器标志的递归:

class YourScene: SKScene {
    
    var gameOver: Bool = false

    func spawnEnemies() {
        let waitAction = SKAction.wait(forDuration: yourDynamicDurationHere)
        self.run(SKAction.sequence([SKAction.run(self.spawnEnemy), waitAction])) {
            if !gameOver {
                spawnEnemies()
            }
        }
    }
}

This solution leverages the completion handler of run method to recursively schedule another execution of the sequence.该解决方案利用run方法的完成处理程序递归地安排序列的另一个执行。 Since each individual SKSequence is created just before it is executed, we can pass in a different wait time for each iteration.由于每个单独的SKSequence都是在执行之前创建的,因此我们可以为每次迭代传递不同的等待时间。

To stop the recursive loop, just set gameOver = true.要停止递归循环,只需设置gameOver = true。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM