Monday, September 22, 2014

HowTo: Implement targeting or follow behavior for sprites with SpriteKit and SKConstraint in SWIFT

Welcome to Part 14 of my blog series about iOS game development.

At the developer conference WWDC, in June this year, Apple showed a new class in SpriteKit: SKConstraint. It can be used to define constraints for the orientation, the distance or the position of SpriteKit nodes. In my todays blog post I'll show how to use SKContraints to implement a follow and targeting behavior. I have updated this tutorial to XCode 6.1!

1. Create a new Project

2. Open the GameScene.swift file and remove the code for creating a label in didMoveToView:

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */


3. Create a global Sprite property:

    var sprite = SKSpriteNode()
    override func didMoveToView(view: SKView) {
        /* Setup your scene here */


4. Create two sprites inside didMoveToView:

       self.backgroundColor = UIColor.blackColor()
        // Create the followed sprite
        sprite = SKSpriteNode(imageNamed:"Spaceship")
        sprite.xScale = 0.15
        sprite.yScale = 0.15
        sprite.position = CGPointMake(100, 100)
        // Create the follower sprite
        let followerSprite = SKSpriteNode(imageNamed:"Spaceship")
        followerSprite.xScale = 0.15
        followerSprite.yScale = 0.15
        followerSprite.position = CGPointMake(150, 150)
        followerSprite.color = UIColor.redColor()

5. Create two constraints inside didMoveToView

One to specify the distance between the two Sprites to implement the follow behavior:

        // Define Constraints for following behavior
        let rangeToSprite = SKRange(lowerLimit: 100.0, upperLimit: 150.0)

        let distanceConstraint = SKConstraint.distance(rangeToSprite, toNode: sprite)

One to specify the orientation of the follower Sprite to the followed Sprite: 

        // Define Constraints for orientation/targeting behavior
   let rangeForOrientation = SKRange(lowerLimit: CGFloat(M_2_PI*7), upperLimit: CGFloat(M_2_PI*7))

        let orientConstraint = SKConstraint.orientToNode(sprite, offset: rangeForOrientation)

Add the constraints to the follower Sprite:

        // Add constraints
        followerSprite.constraints = [orientConstraint, distanceConstraint]

6. Replace the code inside the touchesBegan method to implement the sprite movement:

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        /* Called when a touch begins */
        for touch: AnyObject in touches {
            let location = touch.locationInNode(self)
            let action = SKAction.moveTo(location, duration: 1)

That's all for today.



  1. I've got a compass at a fixed position on the screen that I am orienting to a waypoint on a large scrolling background. What would you recommend to orient towards the waypoint as it the background scrolls as it contains the waypoint? When implementing the above it the orientation seems to be fixed.

    1. Not sure, but I think constraints are only working for nodes which are on the visible screen. If you try to orient to something outside of your screen this may not work.
      Try this:
      1. Calculate the vector to your target node
      2. Minimize is by a factor which will result on a position on your screen (e.g. factor 10)
      3. Position an invisible node on this position
      4. Orient to this node.

      I hope this helps

  2. SKRange(lowerLimit: CGFloat(M_2_PI*7), upperLimit: CGFloat(M_2_PI*7))

    How did you come up with this range? Try to understand. Thanks

    1. To be honest, I've tried several values and 7 fits best for me.

  3. This comment has been removed by the author.