Laurent Maquet Laurent Maquet - 3 months ago 15
Swift Question

How do I make a For loop waiting for a callback before iterating to the next element?

I'm quite new to programming, and I have a For loop that is supposed to run all the levels of my game, one after the other.

var level = 1

for stage in stages {

runLevel(level, stageDef: stage) { _ in
if level < stages.count {
print("Skipping to level \(level + 1)")
level += 1
}
}
}


Each level is run by the runLevel function which provides a callback when the action ends.

I'd like to know how to set up this For loop so that it waits for the callback before iterating to the next level.

For now, my problem is that the first level is repeated as many time as number of levels, and nearly simultaneously because the loop doesn't wait for a level to finish before skipping to the next iteration.

Also, feel free to tell me if you think my For loop approach is not the most appropriate.

Here is the runLevel function

func runLevel(levelId: Int, stageDef:Dictionary<String, String>, completionBlock:(completed: Bool)->()) {

var helicoAction = SKAction()
var herculeAction = SKAction()
var mirageAction = SKAction()



print("Processing level \(levelId)")
self.levelLabel.text = "Level \(levelId)"


if let strNbHelico = stageDef["helicopter"] {
if let nbHelico = Int(strNbHelico) {
print("nbHelico: \(nbHelico)")
helicoAction = SKAction.repeatAction(SKAction.sequence([SKAction.waitForDuration(NSTimeInterval(3), withRange: NSTimeInterval(3)),SKAction.runBlock(addHelico2)
]), count: nbHelico)

}
}
if let strNbHercule = stageDef["hercule"] {
if let nbHercule = Int(strNbHercule) {
print("nbHercule: \(nbHercule)")
herculeAction = SKAction.repeatAction(SKAction.sequence([SKAction.runBlock(addHercule),
SKAction.waitForDuration(NSTimeInterval(3), withRange: NSTimeInterval(5))
]), count: nbHercule)

}
}
if let strNbMirage = stageDef["mirage"] {
if let nbMirage = Int(strNbMirage) {
print("nbMirage: \(nbMirage)")
mirageAction = SKAction.repeatAction(SKAction.sequence([SKAction.runBlock(addHercule),
SKAction.waitForDuration(NSTimeInterval(3), withRange: NSTimeInterval(5))
]), count: nbMirage)

}
}

let groupedActions = SKAction.group([helicoAction, herculeAction, mirageAction])
runAction(SKAction.sequence([groupedActions,SKAction.waitForDuration(1)]), completion: {
print("action completed")
completionBlock (completed: true)
})


}


Thanks for your help

Answer

For that you can create function like this

func perfomSomethinOn(lavel: Int) {

    runLevel(level, stageDef: stage) { _ in
        if (level + 1) < stages.count {
             print("Skipping to level \(level + 1)")
             self.perfomSomethinOn(lavel + 1)
        }
    }
}

Now call this function like this

self.perfomSomethinOn(1)
Comments