2

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!

Shankar BS
  • 8,394
  • 6
  • 41
  • 53
B. Holder
  • 37
  • 1
  • 4

3 Answers3

1

try this, may be due to same time u are adding the actions for each balls,

smallBall.runAction(SKAction.sequence([SKAction.waitForDuration(0.1 + (i * 0.35/2)), moveAction, SKAction.runBlock({
                smallBall.removeFromParent()
            })])) // delay added (0.1 + (increment the daly))

try this

Shankar BS
  • 8,394
  • 6
  • 41
  • 53
1

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.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • It worked! Thank you so much! Only problem I encountered was I had to explicitly declare that the variable i was a double, but other than that everything works nicely! Thanks again! :D – B. Holder Oct 14 '16 at 03:39
0

Your problem is you are calling runAction on each iteration of your for loop. This means that all your actions will run concurrently.

What you want to do is create an array of actions. then after the for loop, run a sequence of actions.

(Note: I took the liberty of cleaning up your 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)
    var sequence = [SKAction]()
    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)
        var ballname = "smallBall”
        switch chanceToSpawn {


        case 61...80:
            //same as case 0…60, smallBall changed to “mediumBall”
            ballname = "mediumBall”

        case 81...99:
            //same as case 0…60, smallBall changed to “largeBall”
            ballname = "largeBall”

        default: ()
        } // ends switch statement

        sequence.append(delay)
        sequence.append(
            SKAction.run()
            {
                [unowned self] in
                let ball = SKSpriteNode(imageNamed: ballName)
                self.addChild(ball)
                ball.xScale = 0.05
                ball.yScale = 0.05
                ball.position = point

                let finalDest = CGPointMake(origin.x, origin.y)
                let moveAction = SKAction.moveTo(finalDest, duration: 5.0)
                let briefWait = SKAction.waitForDuration(0.1)
                let remove = SKAction.removeFromParent()
                let moveSeq = SKAction.sequence([briefWait ,moveAction,remove])
                ball.runAction(moveSeq)

            }
        )
    }//ends for loop


   self.run(SKAction.sequence(sequence))
}//end didMoveToView
Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44