1

How can I animate a SKSpriteNode from a array of CGPoints in swift? I would also like the SKSpriteNode to rotate towards the next position it is going to. Any help would be appreciated.

2 Answers2

1

You can do it like this:

import SpriteKit

class GameScene: SKScene,SKSceneDelegate {


    override func didMove(to view: SKView) {

        //1. create points
        let points = [CGPoint(x:120,y:20),CGPoint(x:220,y:20),CGPoint(x:40,y:320)]

        var actions = [SKAction]()

        //2. Create actions
        for point in points {
            actions.append(SKAction.move(to: point, duration: 1))
        }

        let sprite = SKSpriteNode(color: .white, size: CGSize(width: 100, height: 100))

        addChild(sprite)

        //3. Create the action sequence from previously created actions
        let sequence = SKAction.sequence(actions)

        //4. Run the sequence (use the key to stop this sequence)
        sprite.run(sequence, withKey:"aKey")

    } 
}
Whirlwind
  • 14,286
  • 11
  • 68
  • 157
  • Thanks, is there any way to rotate the SKSpriteNode towards the direction it is moving to? –  May 08 '17 at 11:50
  • Also, can I make the speed a constant for each animation? –  May 08 '17 at 11:51
  • Look at the Aiming part of this [answer](http://stackoverflow.com/a/36235426/3402095). To solve constant speed, use formula Time = Distance / Speed. If you get stuck, ask another question and me or somebody else will answer it, because this is different topic and you already have an answer to your original question... – Whirlwind May 08 '17 at 11:58
  • surprised you took this approach instead of making a CGPath – Knight0fDragon May 08 '17 at 13:33
  • @Knight0fDragon Well, I guess I just have put the same amount of effort in answer as OP did in his question :) I don't know, this is the first thing that came to my mind and I wrote an answer in 30 seconds :) But yeah, maybe your way is more suitable for OP. Also it seems more memory wise, but without testing, who knows ;) (I mean I don't know what `CGMutablePath` does behind the scenes). – Whirlwind May 08 '17 at 15:02
1

As per @KnightOfDragon's suggestion, you can make a path and make the node to follow it, like this:

class GameScene: SKScene {


    override func didMove(to view: SKView) {


        //1. create points
        let points = [
            CGPoint(x:frame.minX,y:frame.minY),
            CGPoint(x:frame.maxX,y:frame.maxY),
            CGPoint(x:frame.maxX,y:frame.midY),
            CGPoint.zero
                      ]

        //2. Create a path
        let path = CGMutablePath()

        //3. Define starting point
        path.move(to: points[0])

        //4. Add additional points
        for point in points[1..<points.count]{

            print("point : \(point)")
            path.addLine(to: point)
        }

        //5. Create an action which will make the node to follow the path
        let action = SKAction.follow(path, speed: 122)

        let sprite = SKSpriteNode(color: .white, size: CGSize(width: 100, height: 100))

        addChild(sprite)

        sprite.run(action, withKey: "aKey")

    }
}

This might be more convenient than accepted answer in the case that you want the node to orient to the path that it follows (zRotation property animates so that the node turns to follow the path).

Whirlwind
  • 14,286
  • 11
  • 68
  • 157