1

I have a spritekit scene and added some sequence of actions to one of it's spriteSceneNode. Say for example,a spriteSceneNode called node1 moving to point1 then it will move to point2 then point3 etc. Its implemented by using "SKAction.moveTo" function.

My question is,

Is it possible to call a custom function when it reaches on each points (point1 or point2 or point3).?

Adding some code here.

 func MoveObjectToAnotherPosition(arrayOfPoints : [CGPoint],object: SKSpriteNode   )  {
    let from   = object.position


    var curPoint1 = object.position


    let move = SKAction.move(to: from ,duration: 0.5)
    var arrayOfMove : [SKAction] = []
    arrayOfMove.append(move)
    for point in (arrayOfPoints ) {
        let move2 = SKAction.move(to: point,duration: 2.5)

       let deltaX = point.x - curPoint1.x
        let deltaY = point.y - curPoint1.y
        let angle = atan2(deltaY, deltaX)
        // let graph =  childNode(withName: "Graph1")?
        print(angle)
        let ang = point.angle(to: curPoint1)
        print(ang)
        let codeToRunWhenReachingPointX = SKAction.run {
            let anglevalue = angle + 90 * self.DegreesToRadians
            self.movObject.zPosition = anglevalue
            print(anglevalue)
        }


        //print(anglevalue)
        let rotate = SKAction.rotate(byAngle: -angle, duration: 0.0)
        arrayOfMove.append(codeToRunWhenReachingPointX)
        arrayOfMove.append(move2)
        curPoint1 = point
    }


    let moveToSequence = SKAction.sequence(arrayOfMove)

    object.run(moveToSequence)
}

Any help?

Araf
  • 510
  • 8
  • 32

1 Answers1

2

Yes, you can call any code when an SKAction completes. To do this, you can create an SKAction that runs any code by using run(_:).

Since you want to call some code when reaching a point X, I would add something like this for each point X:

let moveToPointX = SKAction.move(to: pointX, duration: someDuration)
arrayOfMove.append(moveToPointX)

let codeToRunWhenReachingPointX = SKAction.run {
     // add whatever code you need, e.g. a closure passed to this function
}
arrayOfMove.append(codeToRunWhenReachingPointX)

Then you can run the sequence of actions as you are now by calling

let moveToSequence = SKAction.sequence(arrayOfMove)
object.run(moveToSequence)

It is worth noting that running the sequence of actions will not wait for codeToRunWhenReachingPointX to complete before moving to the next point. Say you have the array of SKActions [m1, c1, m2, c2], where the m's are your move actions, and the c's are your "run code" actions. When you run this sequence, this will happen: m1 will run and when it completes c1 will run, and then without waiting for c1 to complete, m2 will run, and when m2 completes c2 will run.

Also have a look at the run(_:completion:) method, which works similarly.

Hope this helps!

JohnV
  • 981
  • 2
  • 8
  • 18
  • What do you mean by "It is worth noting that the running the sequence of actions will not wait for codeToRunWhenReachingPointX to complete"? The block executes all in 1 frame unless you throw it onto a different thread. If the block hasn't completed your app should lock up and lag – Knight0fDragon Jun 29 '17 at 14:16
  • I might be wrong on this, but put a big function to execute in that block (or a function that calls other functions, does other animation, etc). You will see the node start moving to the 2nd point before that "big function" completes. At least that's what I've seen in my simple spritekit projects. Maybe I'm wrong. Is there is a better way? – JohnV Jun 29 '17 at 14:38
  • I will have to test that out (haven't done it in a while), because I used to come across this problem and had to use customAnimation to get it to move onto the next action – Knight0fDragon Jun 29 '17 at 14:43
  • 1
    @JohnV i make the changes with SKAction.run but my skSpritenode object zposition not updated but the function triggered currectly – Araf Jun 29 '17 at 15:01
  • 2
    @Araf I must admit I'm a bit lost here... Is the code correct that you change the zposition of movObject, but you run the sequence of SKActions on object? – JohnV Jun 29 '17 at 20:20
  • 1
    @Araf as a side note, when you capture self in a closure, like you are doing in the SKAction.run {... , add "[unowned self] in" (without the ") just before your code in the closure, as in: SKAction.run { [unowned self] in // and then the rest of your code. Otherwise, you create a strong reference to self, and it can mess with the ARC and lead to memory leaks. – JohnV Jun 29 '17 at 20:24
  • @JohnV thanks for the help and accepting it. Could you please do me a favor? I had an another which is not getting much response. Can you please drop some suggestions there. Attaching the URL https://stackoverflow.com/questions/44799033/how-to-access-the-object-of-navigation-graph-in-spritekit-scene-editor Thanks in Advance :) – Araf Jun 30 '17 at 05:45