2

i have a node bear that has two skactions on it (in a group). Action bearmove is on a loop, while moveUp is not, moveUP should only happen once.

let moveUp=SKAction.moveTo(y:50,duration:1.0)
let bearAnimate=[SKTexture(imageNamed:"image1"),SKTexture(imageNamed:"image2"),SKTexture(imageNamed:"image3"),SKTexture(imageNamed:"image2")]

let bearmove=SKAction.animate(with: bearAnimate,timePerFrame:0.3)
let bearRep=SKAction.repeatForever(bearmove)

 let bearRun = SKAction.group([moveUp, bearRep])
 bear.run(bearRun)

I want to know when moveUp completed/ stoped running. I tried:

if !bear.hasActions(){
   print("stoped moving")
}

but since bearAnimate is on a loop and never stops. This line of code never gets read. Any ideas how to detect one of the actions in a group?

  • 1
    here is a way to use extensions and keys to know when Actions finish, and then do something: http://stackoverflow.com/a/37722911/2109038. This is more complex than @Mark Brownsword's very elegant and simple technique. – Confused Jan 06 '17 at 08:19
  • @Confused that will not help Cindy Smith, What you provided was a completion handler for when a node is running an action with a key, Cindy needs to know when an individual action as a part of a group of actions is done. – Knight0fDragon Jan 06 '17 at 20:46
  • Would a completion handler on an action within a group get called? @Knight0fDragon – Confused Jan 07 '17 at 04:34
  • @Confused Actions do not have completion handlers, so no – Knight0fDragon Jan 07 '17 at 04:38
  • Then what's the term for this: `func run(action:SKAction,completion:()->())` if it's not called a completion handler? @Knight0fDragon – Confused Jan 07 '17 at 04:39
  • @Confused That is on an `SKNode`, not an `SKAction`, if you read the original question again, you will see the OP tried using that, but failed due to an action in a group having an infinite loop. Infinite loop means action can never end – Knight0fDragon Jan 07 '17 at 04:41
  • If, for example: `moveup = run(action:SkAction, completion:() ->())`, and is the first in a group, why wouldn't the completion of `moveup` get called when the SKAction completed, regardless of what the other actions in the group are? – Confused Jan 07 '17 at 04:45

1 Answers1

3

You could create another action to handle what happens after moving, then run these actions as a sequence.

let afterMoveHandler = SKAction.runBlock({
    // Your code here
})

let moveSequence = SKAction.sequence([moveUp, afterMoveHandler])
let bearRun = SKAction.group([moveSequence, bearRep])

If you want an extension of SKAction to do what you are looking for, consider the following:
(Code is Swift 3)

extension SKAction
{
    static func run(action:SKAction,completion:()->()) -> SKAction
    {
       return SKAction.sequence([action, SKAction.run(completion)]
    }

}

Usage:

let moveUpEvent = SKAction.run(action:moveUp){/*do something here*/}
let bearRun = SKAction.group([moveUpEvent , bearRep])
Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44
Mark Brownsword
  • 2,287
  • 2
  • 14
  • 23