Parallax Effect in Spritekit
In this example we will build a simple application that has a static background and 4 clouds moving at different speeds to depict a parallax effect.
Spritekit framework has been used in this sample.
Play the video for the final output
// // KSAppDelegate.h // Parallax Effect // // Copyright (c) 2014 Debasis Das. All rights reserved. // #import <Cocoa/Cocoa.h> #import <SpriteKit/SpriteKit.h> @interface KSAppDelegate : NSObject <NSApplicationDelegate> @property (assign) IBOutlet NSWindow *window; @property (assign) IBOutlet SKView *skView; @end
// // KSAppDelegate.m // Parallax Effect // // Created by Debasis Das on 3/10/14. // Copyright (c) 2014 Debasis Das. All rights reserved. // #import "KSAppDelegate.h" #import "KSMyScene.h" @implementation KSAppDelegate @synthesize window = _window; - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { /* Pick a size for the scene */ SKScene *scene = [KSMyScene sceneWithSize:CGSizeMake(1024, 768)]; /* Set the scale mode to scale to fit the window */ scene.scaleMode = SKSceneScaleModeAspectFit; [self.skView presentScene:scene]; self.skView.showsFPS = YES; self.skView.showsNodeCount = YES; self.skView.showsDrawCount = YES; } - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { return YES; } @end
//
// KSMyScene.h
// Parallax Effect
//
// Copyright (c) 2014 Debasis Das. All rights reserved.
//
#import <SpriteKit/SpriteKit.h>
@interface KSMyScene : SKScene
@end
// // KSMyScene.m // Parallax Effect // // Created by Debasis Das on 3/10/14. // Copyright (c) 2014 Debasis Das. All rights reserved. // // #import "KSMyScene.h" @implementation KSMyScene { NSTimeInterval _lastUpdateTime; NSTimeInterval _dt; CGPoint _velocity; } -(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { /* Setup your scene here */ self.backgroundColor = [SKColor whiteColor]; //Initialize the background. The background will be fixed frame and the clouds will move on top of the background SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:@"background"]; background.position = CGPointMake(self.size.width/2, self.size.height/2); //Set the position to the center of the screen. Mac position is different from iOS background.name =@"background"; [self addChild:background]; SKSpriteNode *sun = [SKSpriteNode spriteNodeWithImageNamed:@"sun"]; sun.position = CGPointMake(100, 700); [sun setScale:0.5]; sun.name = @"sun"; [self addChild:sun]; SKSpriteNode *cloudOne = [SKSpriteNode spriteNodeWithImageNamed:@"cloud1"]; cloudOne.position = CGPointMake(700, 400); cloudOne.name = @"cloud1"; [self addChild:cloudOne]; SKSpriteNode *cloudTwo = [SKSpriteNode spriteNodeWithImageNamed:@"cloud2"]; cloudTwo.position = CGPointMake(500, 400); [cloudTwo setScale:0.75]; cloudTwo.name = @"cloud2"; [self addChild:cloudTwo]; SKSpriteNode *cloudThree = [SKSpriteNode spriteNodeWithImageNamed:@"cloud3"]; cloudThree.position = CGPointMake(500, 500); [cloudThree setScale:0.6]; cloudThree.name = @"cloud3"; [self addChild:cloudThree]; SKSpriteNode *cloudFour = [SKSpriteNode spriteNodeWithImageNamed:@"cloud4"]; cloudFour.position = CGPointMake(700, 600); [cloudFour setScale:0.55]; cloudFour.name = @"cloud4"; [self addChild:cloudFour]; } return self; } -(void)update:(CFTimeInterval)currentTime { /* Called before each frame is rendered */ if(_lastUpdateTime) { _dt = currentTime - _lastUpdateTime; } else { _dt=0; } _lastUpdateTime = currentTime; [self moveBackground]; } -(void)moveBackground { [self enumerateChildNodesWithName:@"cloud1" usingBlock:^(SKNode *node, BOOL *stop){ SKSpriteNode *bg = (SKSpriteNode *)node; CGPoint bgVelocity = CGPointMake(-50.0, 0); CGPoint amountToMove = CGPointMultiplyScalar (bgVelocity,_dt); bg.position = CGPointAdd(bg.position,amountToMove); if (bg.position.x <= -bg.size.width/2) { bg.position = CGPointMake(1600 , 400); } }]; [self enumerateChildNodesWithName:@"cloud2" usingBlock:^(SKNode *node, BOOL *stop){ SKSpriteNode *bg = (SKSpriteNode *)node; CGPoint bgVelocity = CGPointMake(-80.0, 0); CGPoint amountToMove = CGPointMultiplyScalar (bgVelocity,_dt); bg.position = CGPointAdd(bg.position,amountToMove); if (bg.position.x <= -bg.size.width/2) { bg.position = CGPointMake(1400 , 400); } }]; [self enumerateChildNodesWithName:@"cloud3" usingBlock:^(SKNode *node, BOOL *stop){ SKSpriteNode *bg = (SKSpriteNode *)node; CGPoint bgVelocity = CGPointMake(-100.0, 0); CGPoint amountToMove = CGPointMultiplyScalar (bgVelocity,_dt); bg.position = CGPointAdd(bg.position,amountToMove); if (bg.position.x <= -bg.size.width/2) { bg.position = CGPointMake(1400 , 600); } }]; [self enumerateChildNodesWithName:@"cloud4" usingBlock:^(SKNode *node, BOOL *stop){ SKSpriteNode *bg = (SKSpriteNode *)node; CGPoint bgVelocity = CGPointMake(-150.0, 0); CGPoint amountToMove = CGPointMultiplyScalar (bgVelocity,_dt); bg.position = CGPointAdd(bg.position,amountToMove); if (bg.position.x <= -bg.size.width/2) { bg.position = CGPointMake(1400 , 700); } }]; } CGPoint CGPointAdd(CGPoint p1, CGPoint p2){ return CGPointMake(p1.x + p2.x, p1.y + p2.y); } CGPoint CGPointMultiplyScalar(CGPoint p1, CGFloat p2){ return CGPointMake(p1.x *p2, p1.y*p2); } @end
Also refer to SpriteKit – Background Infinite Scroll
Download the source code from hereSpritekit Parallax Effect Sample Code
Good job! Good resource! Thanks!
Thanks a lot, nice one. Is the source code available?
I will upload the source code in a couple of minutes
Hi Glen,
The post has been updated with the source code download link.
Regards
Debasis
Exactly that I want need and I want. Thanks for code that you have uploaded. Keep