Reputation: 3541
I have a for loop that runs 10 times, each time creating a node and adding it to the scene. However, I want there to be a delay in between each node being added (add a node, wait a second, add a node, wait a second, etc.)
However, after the first 1 second, all 10 nodes are added at the same time. How can I achieve this desired effect of waiting a second in between each node being added?
Here is my code:
EDIT:
func createText(correct: Bool) {
let text = SKNode()
var line: String!
addChild(text)
if correct {
line = (GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(happyLines) as! [String])[0]
} else {
line = (GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(sadLines) as! [String])[0]
}
var xPos = self.frame.midX + 300
var yPos = self.frame.midY
var spaces = 1
// For each character in sentence, create a node of it
for character in line.characters {
runAction(SKAction.waitForDuration(1.0)) {
if spaces == 4 {
spaces = 0
print("space")
xPos = self.frame.midX + 300
yPos -= 30
}
xPos += 10
if character != " " {
let letter = SKLabelNode(fontNamed: GameScene.fontName)
letter.fontSize = 14 * GameScene.fontScale
letter.position = CGPoint(x: xPos, y: yPos)
letter.text = String(character)
text.addChild(letter)
} else {
spaces += 1
xPos += 10
}
}
}
runAction(SKAction.waitForDuration(2.0)) {
text.removeAllChildren()
text.removeFromParent()
}
}
Upvotes: 2
Views: 711
Reputation: 9795
You can achieve this using actions.
First, create actions for the delay and adding the node to the scene.
let waitAction = SKAction.wait(forDuration: 1)
let addNodeAction = SKAction.run {
let node = SKSpriteNode(imageNamed: "example")
self.addChild(node)
}
Next, create a sequence of actions so that the delay always occurs before the node is added to the scene.
let sequenceAction = SKAction.sequence([waitAction, addNodeAction])
Next, create an action that repeats the sequence 10 times.
let repeatAction = SKAction.repeat(sequenceAction, count: 10)
Finally, run this action and watch the nodes appear!
run(repeatAction)
EDIT:
To solve your second question in the comments about needing access to the current character (making each action where the node is added slightly different), loop through your characters
to build a sequence of actions, and then run that action.
var actions = [SKAction]()
let waitAction = SKAction.wait(forDuration: 1)
for character in line.characters {
let addNodeAction = SKAction.run {
let node = SKSpriteNode(imageNamed: "example")
// use the character variable here
self.addChild(node)
}
actions.append(waitAction)
actions.append(addNodeAction)
}
let sequenceAction = SKAction.sequence(actions)
run(sequenceAction)
Upvotes: 1
Reputation: 990
How about this? (not tested :)
for (i, character) in line.characters.enumerate() {
runAction(SKAction.waitForDuration(Double(i) * 1.0)) {
// rest of your for loop
So you enumerate through the characters, where i is the i-th character, starting at 0. With each character, you just multiply its index position in the string with the 1 second interval to give you the wait duration.
Upvotes: 1