Smoother Camera Motion in SpriteKit Using lerp

Share This Post!
Share on FacebookTweet about this on TwitterShare on LinkedInShare on Google+Email this to someone

Whilst working on Ghost Dash: Scared Of The Dark, I did some experimentation with smooth camera motion in SpriteKit.

I wanted the camera motion in SpriteKit to feel smooth, comfortable, natural and non-jerky.

The standard approach with managing camera movement in SpriteKit is to create a scene, in that scene create a game world and place the player into the world.

Then as the player moves, the camera needs to follow the player and this can be done in one of two ways, the first is to introduce a camera node or alternatively you can simply adjust the position of the world with respect to the scene. The latter approach is simpler in my opinion and the one shown below.


Enter your email below and receive everything you need
to get started with coding! ALL 100% FREE!

Adjusting the position of the world after every physics simulation can give a jerky feel to the camera movement because it tracks the player position too precisely and the player always remains dead center in the scene. This can feel quite static.

Jerky Camera Motion in SpriteKit – Without lerp

The simple approach leading to static, jerky camera movement:

@implementation GameScene { 
   SKNode *world; //game world
   SKNode *player; //player
}

-(void)didMoveToView:(SKView *)view {
   self.anchorPoint = CGPointMake(0.5, 0.5);
   //create game world
   world = [SKNode node];
   [self addChild:world];

   //create player and add to game world
   ...
   [world addChild:player];
}

- (void)didSimulatePhysics {
   [self centerOnNode];
}

- (void)centerOnNode {
    CGPoint positionInScene = [self convertPoint:player.position fromNode:player.parent];

   CGFloat adjustedX = world.position.x - positionInScene.x;
   CGFloat adjustedY = world.position.y - positionInScene.y;
   world.position = CGPointMake(adjustedX, adjustedY);
}

Smoother Camera Motion in SpriteKit – With lerp

A slightly more complex approach is to use a precise linear interpolation function (lerp) to work out where the camera should move to and start to move it in that direction. Adding some damping and experimenting with parameters will give the desired effect where the camera follows the player smoothly and almost looks like it’s trying to catch up with the player. This additionally gives the impression of speed.

@implementation GameScene { 
   SKNode *world; //game world
   SKNode *player; //player
   CGPoint previousPosition; //previous position of world
...
}

-(void)didMoveToView:(SKView *)view {
   self.anchorPoint = CGPointMake(0.5, 0.5);
   //create game world
   world = [SKNode node];
   [self addChild:world];

   //create player and add to game world
   ...
   [world addChild:player];
   previousPosition = [self position];
}

- (void)didSimulatePhysics {
   [self centerOnNode];
}

- (void)centerOnNode {
   //move camera using lerp
   CGPoint currentPosition = [self position];
   CGFloat x = [self lerpPrec:previousPosition.x b:currentPosition.x t:0.03] - 20;
   CGFloat y = ([self lerpPrec:previousPosition.y b:currentPosition.y t:0.03] - 20) * 0.4;
   previousPosition = currentPosition;

   //smoother camera movement
   SKAction *move = [SKAction moveTo:CGPointMake(x, y) duration: 0.2];
   [world runAction:move];
}

- (CGPoint)position {
   CGPoint positionInScene = [self convertPoint:player.position fromNode:player.parent];
   return CGPointMake(world.position.x - positionInScene.x, world.position.y - positionInScene.y);
}

- (CGFloat)lerpPrec:(CGFloat)a b:(CGFloat)b t:(CGFloat)t {
   return (1 - t) * a + t * b;
}

So there you have it, a quick tutorial with a code example on how to get smooth camera motion in SpriteKit!

Check out the build log for Ghost Dash: Scared Of The Dark

 

Share This Post!
Share on FacebookTweet about this on TwitterShare on LinkedInShare on Google+Email this to someone

One Reply to “Smoother Camera Motion in SpriteKit Using lerp”

Comments are closed.