Search code examples
swiftfor-loopsprite-kitswitch-statementspawning

for loop not executing code sequencially (swift + spritekit)


Here's my code:

override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    let origin = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))

    let delay = SKAction.waitForDuration(2.0)

    for (var i = 0; i < 6; i++) {
        //generate a random point on a circle centered at origin with radius of 500
        let point = randomPointOnCircle(500, center: origin)

        let chanceToSpawn = arc4random_uniform(100)

        switch chanceToSpawn {

        case 0...60:

            self.runAction(delay){
                let smallBall = SKSpriteNode(imageNamed: "smallBall”)
                self.addChild(smallBall)
                smallBall.xScale = 0.05
                smallBall.yScale = 0.05
                smallBall.position = point

                let finalDest = CGPointMake(origin.x, origin.y)
                let moveAction = SKAction.moveTo(finalDest, duration: 5.0)
                smallBall.runAction(SKAction.sequence([SKAction.waitForDuration(0.1), moveAction, SKAction.runBlock({
                    smallBall.removeFromParent()
                })]))
                delay
            }

            break

        case 61...80:
            //same as case 0…60, smallBall changed to “mediumBall”
            break
        case 81...99:
            //same as case 0…60, smallBall changed to “largeBall”
            break
        default:
            break
        } // ends switch statement
    }//ends for loop



}//end didMoveToView

Basically I have balls that spawn on a random point on a circle and move towards the center. But the problem I am having is that no matter how I rearrange things (or rewrite things, i.e., trying different loops or defining functions for spawning the ball and the movement of the ball and simply calling them from inside the switch statement) all of the balls spawn at the same time. I am trying to make it so they spawn one after the other (meaning a ball spawns, the thread waits a few seconds, then spawns another ball.), and I can't seem to figure out why each ball is spawning at the same time as all the other balls.

I'm fairly new to Swift/Spritekit programming and I feel like I'm overlooking some small detail and this is really bugging me. Any help appreciated!


Solution

  • For loops are executed faster than you think! Your for loop is probably executed instantly.

    "Why is that? I have already called self.runAction(delay) to delay the for loop!" you asked. Well, the delay action doesn't actually delay the for loop, unfortunately. It just delays the other actions you run on self.

    To fix this, try delaying different amounts, dependind on the for loop counter:

    self.runAction(SKAction.waitForDuration(i * 2 + 2)) { ... }
    

    This way, balls will appear every two seconds.