Scrolling in Sprite Kit Tutorial

With scrolling in Sprite Kit you can add dynamics to your game. In this tutorial we will let a background image scroll to the right. We will achieve this by copying the image and position it to the right of the original image. Then we change the x-position, so it appears we have an endless-scrolling background.

Open Xcode and create a new SpriteKit Game. For product name, use ScrollingSpriteKitTutorial and then fill out the Organization Name, Company Identifier and Class Prefix fields with your customary values. Make sure only iPhone is selected in Devices.

As we use side-scrolling we need to change the orientation of the device. Go to the project settings and under the Deployment Info section deselect the Portrait Orientation.

Next, in ViewController.h we need will move the code from viewDidLoad to viewWillLayoutSubviews. In viewDidLoad the properties are not set when the View is already displayed so it It is better to initialize the scene when our view is ready to be shown and everything has been set. Change the viewDidLoad and viewWillLayoutSubviews methods to

- (void)viewDidLoad
[super viewDidLoad];

- (void) viewWillLayoutSubviews
[super viewWillLayoutSubviews];

// Configure the view.
SKView * skView = (SKView *)self.view;
if (!skView.scene) {
skView.showsFPS = YES;
skView.showsNodeCount = YES;

// Create and configure the scene.
SKScene * scene = [[MyScene alloc] initWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;

// Present the scene.
[skView presentScene:scene];

Next, we will create a class for our scrolling background. Add a new File to the projects name it ScrollingBackground with a subclass of SKSpriteNode. Change ScrollingBackground.h to

#import <SpriteKit/SpriteKit.h>

@interface ScrollingBackground : SKSpriteNode

- (id)initWithBackground:(NSString *)background

- (void)update:(NSTimeInterval)currentTime;


The initWithBackground:size:speed method is the designated initializer. In the update method we will do the actual scrolling. Go to ScrollingBackground.m and declare the following properties.

@interface ScrollingBackground ()

@property (nonatomic, strong) SKSpriteNode *background;
@property (nonatomic, strong) SKSpriteNode *clonedBackground;
@property (nonatomic) CGFloat currentSpeed;


Next, implement the initWithBackground:size:speed method

- (id)initWithBackground:(NSString *)background
self = [super init];
if (self)
// load background image
self.background = [[SKSpriteNode alloc] initWithImageNamed:background];

// position background
self.position = CGPointMake(size.width / 2, size.height / 2);

// speed
self.currentSpeed = speed;

// create duplicate background and insert location
SKSpriteNode *node = self.background;
node.position = CGPointMake(0, self.size.height);

self.clonedBackground = [node copy];
CGFloat clonedPosX = node.position.x;
CGFloat clonedPosY = node.position.y;
clonedPosX = -node.size.width;

self.clonedBackground.position = CGPointMake(clonedPosX, clonedPosY);

[self addChild:node];
[self addChild:self.clonedBackground];

return self;

We load the image and position it to the center. Next we set our speed. We need it later in the update method. Next, we create a copy of our background and we will position it on the right side of our original background. Finally we will add the original and cloned backgrounds to the ScrollingBackground object. Next, implement the update method.

- (void)update:(NSTimeInterval)currentTime
CGFloat speed = self.currentSpeed;
SKSpriteNode *bg = self.background;
SKSpriteNode *cBg = self.clonedBackground;

CGFloat newBgX = bg.position.x, newBgY = bg.position.y,
newCbgX = cBg.position.x, newCbgY = cBg.position.y;

newBgX += speed;
newCbgX += speed;
if (newBgX >= bg.size.width) newBgX = newCbgX - cBg.size.width;
if (newCbgX >= cBg.size.width) newCbgX = newBgX - bg.size.width;
bg.position = CGPointMake(newBgX, newBgY);
cBg.position = CGPointMake(newCbgX, newCbgY);

First, we will initialize the variables to save some typing. Next we update the X-coordinates with the speed. The if statement will check if the X-coordinate is beyond the background. If so, the position will be updated to the beginning of the other background. The ScrollingBackground class is finished now so we need to use this class in the MyScene class of Sprite Kit. First, in MyScene.h import the ScrollingBackground header file.

#import "ScrollingBackground.h"

Add a ScrollingBackground property.

@interface MyScene ()

@property (nonatomic,strong) ScrollingBackground *scrollingBackground;


Now we need an image to use for our scrolling background. Download the image here and add it to the project. Next we change the initWithSize method to

- (id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
/* Setup your scene here */

NSString *imageName = @"clouds.jpg";
self.scaleMode = SKSceneScaleModeFill;

ScrollingBackground *scrollingBackground = [[ScrollingBackground alloc] initWithBackground:imageName size:size speed:2.0];
self.scrollingBackground = scrollingBackground;

[self addChild:scrollingBackground];
return self;

We call our class with our image name, the size of the scene and with a speed of 2.0. The scrolling background is then added to the scene. Finally, change the update method to 

- (void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
[self.scrollingBackground update:currentTime];

The update method of the ScrollingBackground class is called. Build and Run the project and you should see a scrolling background.

You can download the source code of the ScrollingSpriteKitTutorial at the ioscreator repository on github.