Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SKAction how to combine withKey and completion

I´m quite new to iOS and Sprite Kit programming and wonder how to combine:

-[SKAction runAction:withKey:]

and

-[SKAction runAction:completion:]

On the one side, I want to prevent a node from running the same action (or action sequence) again, on the other, I want to react to the termination of an action, but there is no method and, as far as I see, no way to use both at the same time.

Thx

like image 607
Macilias Avatar asked Feb 17 '14 15:02

Macilias


3 Answers

Use +runBlock: action in +sequence: like this:

SKAction *yourAction = ...

SKAction *completion = [SKAction runBlock:^{
    // Your code.
}];
SKAction *sequence = [SKAction sequence:@[ yourAction, completion ]];

[node runAction:sequence withKey:yourKey];

If you use this multiple times, create SKNode category with such method:

- (void)runAction:(SKAction *)action withKey:(NSString *)key completion:(void(^)(void))block;
like image 169
Tricertops Avatar answered Nov 18 '22 07:11

Tricertops


This is a nice solution for Swift 2.x (update to Swift 3.x here below..) created by Daniel L. Alves, using SKNode extension:

extension SKNode
{
    func runAction( action: SKAction!, withKey: String!, optionalCompletion: dispatch_block_t? )
    {
        if let completion = optionalCompletion
        {
            let completionAction = SKAction.runBlock( completion )
            let compositeAction = SKAction.sequence([ action, completionAction ])
            runAction( compositeAction, withKey: withKey )
        }
        else
        {
            runAction( action, withKey: withKey )
        }
    }
}

Update to Swift 3.x

extension SKNode
{
    func run(action: SKAction!, withKey: String!, optionalCompletion:((Void) -> Void)?) {
        if let completion = optionalCompletion
        {
            let completionAction = SKAction.run(completion)
            let compositeAction = SKAction.sequence([ action, completionAction ])
            run(compositeAction, withKey: withKey )
        }
        else
        {
            run( action, withKey: withKey )
        }
    }

    func actionForKeyIsRunning(key: String) -> Bool {
        return self.action(forKey: key) != nil ? true : false
    }
}
like image 27
Alessandro Ornano Avatar answered Nov 18 '22 07:11

Alessandro Ornano


If you want to react to the termination of an action, yes you need to use SKAction runAction:(SKAction*) completion ^{ "Your special code here" }. This will execute your special code on the termination of the action.

When you use the SKAction runAction:(SKAction*) withKey:(NSString*), if your action already have a key, you can retrieve the action.
If an action using the same key is already running, it is removed before the new action is added.

like image 1
Vincent Dondain Avatar answered Nov 18 '22 06:11

Vincent Dondain