HUD iOS ObjectiveC Parallax Effect SpriteKit

HowTo: Implement a HUD with SpriteKit

Welcome to Part 8 of my blog series about game development: HUD with SpriteKit

Today I’ll add a HUD (head up display) to the SpriteKit Scene. The HUD shows the remaining lives, current, level, score and has the option to pause the game:

Create the HUD:

1. Create a new SpritKit project in Xcode:


2. Hide the status bar: (Add ‘View controller-based status bar appearance = No’ to the plist file)


3. Add properties for current level and score to MyScene.h

#import <SpriteKit/SpriteKit.h>
@interface MyScene : SKScene
@property int Score;
@property int Level;

4. Add the properties for the UIElements.

I’ve declared them inside the MyScene.m file, because they will only be used inside this class and can be private: 

#import “MyScene.h”
// Private properties
@interface GameScene ()
    @property (nonatomic, retain) SKSpriteNode* LifeNode1;
    @property (nonatomic, retain) SKSpriteNode* LifeNode2;
    @property (nonatomic, retain) SKSpriteNode* LifeNode3;
    @property (nonatomic, retain) SKLabelNode* ScoreNode;
    @property (nonatomic, retain) SKLabelNode* LevelNode;
    @property (nonatomic) int Lifes;
@implementation GameScene

5. Create the HUD

// Adds the HUD to the scene
-(void)createHUD {
    // root node with black background
    SKSpriteNode* hud = [[SKSpriteNode alloc] initWithColor:[UIColor blackColor] size:CGSizeMake(self.size.width, self.size.height*0.05)];
    hud.anchorPoint=CGPointMake(0, 0);
    hud.position = CGPointMake(0,self.size.height-hud.size.height);
    [self addChild:hud];
    // remaining/lost lifes0,
    self.LifeNode1 = [[SKSpriteNode alloc] initWithImageNamed:@”Spaceship”];
    self.LifeNode1.size=CGSizeMake(hud.size.height-2, hud.size.height-2);
    self.LifeNode1.position=CGPointMake(self.LifeNode1.size.width, hud.size.height/2);
    [hud addChild:self.LifeNode1];
    self.LifeNode2 = [[SKSpriteNode alloc] initWithImageNamed:@”Spaceship”];
    self.LifeNode2.size=CGSizeMake(hud.size.height-2, hud.size.height-2);
    self.LifeNode2.position=CGPointMake(self.LifeNode2.size.width*2.5, hud.size.height/2);
    [hud addChild:self.LifeNode2];
    self.LifeNode3 = [[SKSpriteNode alloc] initWithImageNamed:@”Spaceship”];
    self.LifeNode3.size=CGSizeMake(hud.size.height-2, hud.size.height-2);
    self.LifeNode3.position=CGPointMake(self.LifeNode3.size.width*4, hud.size.height/2);
    [hud addChild:self.LifeNode3];
    // current level
    self.LevelNode = [[SKLabelNode alloc] init];
    self.LevelNode.position = CGPointMake(hud.size.width/2, 1);
    self.LevelNode.text=@”Level 1″;
    [hud addChild:self.LevelNode];
    // pause button
    SKLabelNode* pauseButton = [[SKLabelNode alloc] init];
    pauseButton.position = CGPointMake(hud.size.width/1.5, 1);
    pauseButton.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;”PauseButton”;
    [hud addChild:pauseButton];
    // score
    self.ScoreNode = [[SKLabelNode alloc] init];
    self.ScoreNode.position = CGPointMake(hud.size.width-hud.size.width*.1, 1);
    [hud addChild:self.ScoreNode];
Start the Project. The Result should look like this:

7. Add Interactions:

Looks nice, but without interactions this is a little boring. Let’s add them!

First of all add two buttons to increase the score and to loose a life:

-(void)addMockUpButtons {
    SKSpriteNode* lifeLost = [[SKSpriteNode alloc] initWithColor:[UIColor redColor] size:CGSizeMake(self.size.width/3, self.size.height*0.1)];”lifeLost”;
    lifeLost.position=CGPointMake(self.size.width/2, lifeLost.size.height*6);
    [self addChild:lifeLost];
    SKSpriteNode* addScore = [[SKSpriteNode alloc] initWithColor:[UIColor greenColor] size:CGSizeMake(self.size.width/3, self.size.height*0.1)];”addScore”;
    addScore.position=CGPointMake(self.size.width/2, lifeLost.size.height*8);
    [self addChild:addScore];

Don’t forget to call this function in the initWithSize method:

[self addMockUpButtons];







8. Now, implement the touch handler:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    // Get the element which is touched:
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];
    // Trigger actions
    if ([ isEqualToString:@”PauseButton”]) {
        [self showPausedDialog];
    } else if ([ isEqualToString:@”lifeLost”]) {
        [self lifeLost];
    } else if ([ isEqualToString:@”addScore”]) {
        [self addScore];
-(void)addScore {
    self.ScoreNode.text=[NSString stringWithFormat:@”%d”,self.Score];
-(void)showPausedDialog {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@”Paused” message:@”” delegate:self cancelButtonTitle:@”Continue” otherButtonTitles:@”Finish!”, nil, nil];
    [alert show];
-(void)lifeLost {
    if (_Lifes==1) {
        [self.LifeNode1 removeFromParent];
        [self showGameOverAlert];
    } else {
        if (self.Lifes==2) {
            [self.LifeNode2 removeFromParent];
        } else if (self.Lifes==3) {
            [self.LifeNode3 removeFromParent];
-(void)showGameOverAlert {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@”Game Over” message:@”” delegate:self cancelButtonTitle:@”OK” otherButtonTitles:nil, nil, nil];
    [alert show];










Now let’s integrate this into the MyFirstGame project:

If you haven’t completed part 7, you can download the project from GitHub: v0.6.1

The result will look like this:

Most code of the sample above can be copied directly. I’ll only list the differences:

1. Different Icons


Instead of the spaceship, I’ll use a ball image. In case of loosing a life, this image will be replaced with a crossed ball. To achieve this just add two new image sets to the Asset catalog:

  • HUD_Ball‘ 
  • HUD_Ball_crossed‘.  

The icons for Retina and Retina-4-inch iPhones are identical:

2. Changes in createHUD method:

// Adds the HUD to the scene
-(void)createHUD {
    // remaining/lost lifes
    self.LifeNode1 = [[SKSpriteNode alloc] initWithImageNamed:@”HUD_Ball”];
    self.LifeNode1.position=CGPointMake(self.LifeNode1.size.width, hud.size.height/2);
    [hud addChild:self.LifeNode1];
    self.LifeNode2 = [[SKSpriteNode alloc] initWithImageNamed:@”HUD_Ball”];
    self.LifeNode2.position=CGPointMake(self.LifeNode2.size.width*2.5, hud.size.height/2);
    [hud addChild:self.LifeNode2];
    self.LifeNode3 = [[SKSpriteNode alloc] initWithImageNamed:@”HUD_Ball”];
    self.LifeNode3.position=CGPointMake(self.LifeNode3.size.width*4, hud.size.height/2);
    [hud addChild:self.LifeNode3];


3. Changes in lifeLost method:

-(void)lifeLost {
    if (_Lifes==1) {
        self.LifeNode3.texture = [SKTexture textureWithImageNamed:@”HUD_Ball_crossed”];
        [self showGameOverAlert];
    } else {
        if (self.Lifes==2) {
            self.LifeNode2.texture = [SKTexture textureWithImageNamed:@”HUD_Ball_crossed”];
        } else if (self.Lifes==3) {
            self.LifeNode1.texture = [SKTexture textureWithImageNamed:@”HUD_Ball_crossed”];

As always you can download the complete project from GitHub: v0.7 That’s all for today. In my next post I’ll show how to organize your code with the ‘#pragma mark‘ directive.