ahoj
ahoj

Reputation: 11

Using waitForDuration() in spriteKit swift

I wanted to wait 2 seconds between generation nodes. So I wrote this code:

override func update(currentTime: CFTimeInterval) {

    let releaseNodes = SKAction.sequence([SKAction.runBlock(self.generateNode),         SKAction.waitForDuration(2)])

    self.runAction(releaseNodes)

}

But it doesn't work. It's generating nodes as crazy. (like 20 in seconds). How can I handle with it? Can anyone help me, please?

Edit: Here is the self.generateNode block

func generateNode(){

    var node: SKSpriteNode = SKSpriteNode(imageNamed: "node")

    fish.anchorPoint = CGPoint(x:CGFloat(-0.5),y:CGFloat(-0.2))        
    fish.position = CGPoint(x:CGFloat(10),y:CGFloat(30))

    var move = SKAction.rotateToAngle(CGFloat(3.14), duration: NSTimeInterval(1))
    var remove = SKAction.removeFromParent()
    var seq = SKAction.sequence([move, remove])      

    node.runAction(seq)

    self.addChild(node)    

}

Upvotes: 1

Views: 1928

Answers (3)

Andrey Gordeev
Andrey Gordeev

Reputation: 32449

I'd better get rid of using update: method and do everything with using SKActions:

- (void)didMoveToView:(SKView *)skView {
    SKAction *wait = [SKAction waitForDuration:2.];
    SKAction *generateNode = [SKAction runBlock:^{ 
        [self generateNode];
    }];
    [self runAction:[SKAction repeatActionForever:
        [SKAction sequence:@[wait, generateNode]]]];
}

Upvotes: 1

duci9y
duci9y

Reputation: 4168

override func update(currentTime: CFTimeInterval) {
    static var previousTime = 0.0
    if (currentTime - previousTime) > 2.0 {
        let releaseNodes = SKAction.runBlock(self.generateNode)
        self.runAction(releaseNodes)
    }
    previousTime = currentTime
}

update(currentTime:) gives you the timestamp of the current frame. Don't forget to use that property.

Also, the last waitForDuration: action won't have a visible effect in your original code.

Upvotes: 0

Literphor
Literphor

Reputation: 498

From apple documentation on the function SKScene.Update()

Performs any scene-specific updates that need to occur before scene actions are evaluated.

So if within update() you're indiscriminately running actions, it will loop indefinitely creating nodes and attempting to run actions.

You should choose a better place to create your scene content. Maybe after viewDidLayoutSubviews()? or, at least in response to some action within your scene.

Edit: It looks like you want to create content, have it move then remove it from the scene. You might be better off just creating a few sprites, saving a reference to them then having them appear, move and disappear whenever you need it. That would be safer.

Upvotes: 1

Related Questions