Search code examples
iosfor-loopswift3sprite-kitskspritenode

How to create SKSprite node one by one in For loop using Swift SpriteKit


I want to create 10 SKSPrite nodes via a For loop. I want the nodes to appear one by one but with my code, all 10 nodes appear at the same time. Increasing the wait duration does not help. Thank you in advance.

for i in 1 ... 10 {

    self.stone[i - 1].position = CGPoint(x: 0 , y: -100)
    self.stone[i - 1].anchorPoint = CGPoint(x: 0.5, y: 0.5)
    self.stone[i - 1].size = CGSize(width: 50, height: 50)
    self.stone[i - 1].physicsBody = SKPhysicsBody(circleOfRadius: 20)
    self.stone[i - 1].physicsBody!.affectedByGravity = false
    self.stone[i - 1].physicsBody!.categoryBitMask = PhysicsCategory.Object1
    self.stone[i - 1].zPosition = 2
    self.addChild(self.stone[i - 1])   

    let actionMove = SKAction.move(to: CGPoint(x: 0, y: 0), duration: 0.3)
    let actionRolling = SKAction.animate(with: stone[i - 1].arrayTexture, timePerFrame: 0.05)
    let actionDelay = SKAction.wait(forDuration: 1.0)
    let actionSequence = SKAction.sequence([actionMove,actionRolling,actionDelay])
    stone[i - 1].run(actionSequence)
}

Solution

  • all your doing in your code is making a loop that creates the nodes, any duration that you apply to those nodes in that loop will affect them all equally. You need an variable outside of the loop that gets incremented in the loop per instance of node.

    var delay: Double = 1.0 
    
    for i in 1 ... 10 {
    
        self.run(.wait(forDuration: delay) {
    
            self.stone[i - 1].position = CGPoint(x: 0 , y: -100)
            self.stone[i - 1].anchorPoint = CGPoint(x: 0.5, y: 0.5)
            self.stone[i - 1].size = CGSize(width: 50, height: 50)
            self.stone[i - 1].physicsBody = SKPhysicsBody(circleOfRadius: 20)
            self.stone[i - 1].physicsBody!.affectedByGravity = false
            self.stone[i - 1].physicsBody!.categoryBitMask = PhysicsCategory.Object1
            self.stone[i - 1].zPosition = 2
            self.addChild(self.stone[i - 1])   
    
            let actionMove = SKAction.move(to: CGPoint(x: 0, y: 0), duration: 0.3)
            let actionRolling = SKAction.animate(with: stone[i - 1].arrayTexture, timePerFrame: 0.05)
            let actionDelay = SKAction.wait(forDuration: 1.0)
            let actionSequence = SKAction.sequence([actionMove,actionRolling,actionDelay])
            stone[i - 1].run(actionSequence)
        }
    
        delay += 1.0
    }