Performing SKAction on a block with random values

Hello.


I have a scene with a node that moves across the view, returns to the original position, and then moves again. With every move, the node's original position, size, speed, and the wait time have to change based on random values. This is what I came so far:


func cloudsFewNode()
    {
        let node1 = SKSpriteNode(imageNamed: "few1")
        node1.name = "node1"

        let actionBlock1 = SKAction.runBlock(
            {
                let originalPosition1 = CGPointMake(0 - node1.frame.size.width,
                                                    self.frame.size.height - CGFloat(Int.randomWithRange(430...470)))
                node1.position = originalPosition1
       
                node1.setScale(CGFloat(Double.randomWithRange(min: 0.6, max: 1.0)))
       
                let wait1 = SKAction.waitForDuration(Double.randomWithRange(min: 2, max: 3))

                let duration1 = Double.randomWithRange(min: 10, max: 30) as NSTimeInterval

                let move1 = SKAction.moveByX(node1.frame.size.width * 2 + self.frame.size.width,
                                             y: 0,
                                             duration: duration1)

                let moveBack1 = SKAction.moveTo(originalPosition1, duration: 0)

                let moveSequence1 = SKAction.sequence([move1, moveBack1, wait1])
       
                node1.runAction(moveSequence1)
        })

        node1.runAction(SKAction.repeatActionForever(actionBlock1))

        addChild(node1)
    }


The scene crashes the application. Also, I plan to have four more similar nodes in the scene, which moves will be dependent on the position of the other nodes.


Thank you so much for your help!

Accepted Reply

This code endlessly repeats the creation and running of new actions, without waiting.


I'd say you don't have to put everything inside runBlock. You can make it like this:


func createNewRandomActions() {
     let move = ...
     let moveBack = ....
     node.runAction(sequence[move, moveBack, SKAction.runBlock({
     self.createNewRandomActions()
})])
}

Replies

This code endlessly repeats the creation and running of new actions, without waiting.


I'd say you don't have to put everything inside runBlock. You can make it like this:


func createNewRandomActions() {
     let move = ...
     let moveBack = ....
     node.runAction(sequence[move, moveBack, SKAction.runBlock({
     self.createNewRandomActions()
})])
}

Agreed.. if you look at the duration of your actionBlock1, it is 0 - Block actions don't inherit the durations of the actions added inside of them. Make sure if you are going to repeat something forever, it has a non-zero duration.

Thanks a lot, pavelgubarev and ljdickey. Now it makes sense.


Solved it by doing the following:



func cloudsFewNode()
{
        ...
        func createRandomActions1()
        {
           node1.setScale(CGFloat(Double.randomWithRange(min: 0.6, max: 1.0)))
           originalPosition1 = ...
           node1.position = originalPosition1
          
           wait1 = SKAction.waitForDuration(Double.randomWithRange(min: 2, max: 3))
           
           duration1 = Double.randomWithRange(min: 10, max: 30) as NSTimeInterval
        }
      
        let move1 = SKAction.moveByX(  node1.frame.size.width * 2 + self.frame.size.width,
                                       y: 0,
                                       duration: duration1)

        let moveBack1 = SKAction.moveTo(originalPosition1, duration: 0)
      
        let moveSequence1 = SKAction.sequence([SKAction.runBlock{createRandomActions1()},move1, moveBack1, wait1])
      
        node1.runAction(SKAction.repeatActionForever(SKAction.sequence([moveSequence1])))
      
        addChild(node1)
}


Cheers!