Sebastijan B.
Sebastijan B.

Reputation: 83

How to animate random repeated actions?

How can I make SKAction.move() to be random and repeatForever?

For example:

let boxPosition = Double.random(in: 100…600)
let boxMove = SKAction.move(to: CGPoint(x: boxPosition, y: 100), duration: 10)

let boxRepeat = SKAction.repeatForever(boxMove)
box.run(boxRepeat)

I know that in above example will not update the value…

I have solution that works but doesn't feel right. The sequence won't work...

import SpriteKit

class GameScene: SKScene {

let box = SKSpriteNode()

override func didMove(to view: SKView) {

    box.texture = SKTexture(imageNamed: "box")
    box.size = CGSize(width: 50, height: 50)
    box.position = CGPoint(x: 200, y: 200)
    addChild(box)
    
    let boxRandom = SKAction.run({
        let boxPosition = Double.random(in: 300...500)
        let boxMove = SKAction.move(to: CGPoint(x: 200, y: boxPosition), duration: 2)
        self.box.run(boxMove)
    })
    
    let boxMove = SKAction.move(to: CGPoint(x: 200, y: 100), duration: 2)
    
    let boxGroup = SKAction.sequence([boxMove, boxRandom])
    let boxRepeat = SKAction.repeatForever(boxGroup)
    box.run(boxRepeat)

}
}

Any suggestion? Thanks for all the answers in advance.

Upvotes: 2

Views: 95

Answers (1)

clns
clns

Reputation: 2304

The SKAction.run takes place instantaneously, so it won't wait for the completion of the SKAction.move inside it.

A simple fix for your code would be to add an SKAction.wait for the same duration as the SKAction.move inside the block to the sequence:

let wait = SKAction.wait(forDuration: 2)

let boxGroup = SKAction.sequence([boxMove, boxRandom, wait])

If you need to use a custom duration for each move action, you could create a method that will run the random move and recursively call the same method when the move completes. Something like this:

override func didMove(to view: SKView) {
    recursiveRandomMove()
}

func recursiveRandomMove() {
    let random = CGFloat.random(in: 100...400)
    let duration = Double.random(0...10) // your custom duration here
    box.run(SKAction.sequence([
        SKAction.moveTo(x: random, duration: duration),
        SKAction.run {
            self.recursiveRandomMove()
        }
    ]))
}

Also consider looking at Drive Game Logic for more control over your outcomes.

Upvotes: 1

Related Questions