How to Make a Game Like Mega Jump With Sprite Kit: Part 2/2

In Part Two of this tutorial series, you’ll finish developing your Uber Jump game by adding accelerometer-driven controls, a scoring system and more. By Toby Stephens.

Leave a rating/review
Save for later
Share

Welcome to the second part of the tutorial series that walks you through using Sprite Kit to create a game like Mega Jump.

In the first part of the tutorial, you created a new Sprite Kit game called “Uber Jump.” You added graphics, a player sprite and some gameplay elements.

In this second part, you’ll use that firm foundation to build an entire level for Uber Jump, including a scoring system. You’ll also add accelerometer support so that your Uber Jumper can move from side to side as well as up and down. When you’re done, you’ll have a completely playable game that you could expand in many different ways.

As with Part One, be sure you are familiar with the basics of Sprite Kit before continuing.

Your level awaits—so let’s jump to it!

Getting Started

If you don’t have it already, grab a copy of the complete project from Part One.

Your level will contain many stars and platforms. Rather than arrange them manually, download this level configuration file. Unzip it and drag Level01.plist into your Xcode project. Make sure that Copy items into destination group’s folder (if needed) is checked and that your UberJump target is selected.

Open Level01.plist and examine its contents. At the root, it has three elements:

  • EndY specifies the height the player must reach to finish the level.
  • Stars defines the positions of all the stars in the level.
  • Platforms defines the positions of all the platforms in the level.

The Stars and Platforms elements each contain two sub-elements:

  • Patterns contains a number of reusable patterns of stars or platforms.
  • Positions specifies where to place the patterns of stars or platforms throughout the level.

jm_level_plist

To better understand the file format, take a look at Stars/Positions/Item 0. This contains three elements telling the game to place stars in a cross pattern positioned at (160, 240).

jm_level_plist1

Now look at Patterns/Cross and you’ll see this pattern is made up of five items, including (x, y) coordinates relative to the position given in Stars/Positions and the type of star, where NORMAL=0 or SPECIAL=1.

jm_level_plist2

This is simply a convenient way of reusing patterns of stars and platforms without having to code the position of every individual object.

rrr

Loading the Level Data

To add support for loading the level from Level01.plist, open MyScene.m and add the following instance variable to the class extension in MyScene.m:

// Height at which level ends
int _endLevelY;

_endLevelY will store the height, or y-value, that the player must reach to finish the level.

Insert the following code into initWithSize:, just before the lines that instantiate and add platform:

// Load the level
NSString *levelPlist = [[NSBundle mainBundle] pathForResource: @"Level01" ofType: @"plist"];
NSDictionary *levelData = [NSDictionary dictionaryWithContentsOfFile:levelPlist];

// Height at which the player ends the level
_endLevelY = [levelData[@"EndY"] intValue];

This loads the data from the property list into a dictionary named levelData and stores the property list’s EndY value in _endLevelY.

Now for the stars and platforms. Begin with the platforms. In initWithSize:, replace the following lines:

// Add a platform
PlatformNode *platform = [self createPlatformAtPosition:CGPointMake(160, 320) ofType:PLATFORM_NORMAL];
[_foregroundNode addChild:platform];

With this code:

// Add the platforms
NSDictionary *platforms = levelData[@"Platforms"];
NSDictionary *platformPatterns = platforms[@"Patterns"];
NSArray *platformPositions = platforms[@"Positions"];
for (NSDictionary *platformPosition in platformPositions) {
  CGFloat patternX = [platformPosition[@"x"] floatValue];
  CGFloat patternY = [platformPosition[@"y"] floatValue];
  NSString *pattern = platformPosition[@"pattern"];

  // Look up the pattern
  NSArray *platformPattern = platformPatterns[pattern];
  for (NSDictionary *platformPoint in platformPattern) {
    CGFloat x = [platformPoint[@"x"] floatValue];
    CGFloat y = [platformPoint[@"y"] floatValue];
    PlatformType type = [platformPoint[@"type"] intValue];

    PlatformNode *platformNode = [self createPlatformAtPosition:CGPointMake(x + patternX, y + patternY)
                                                         ofType:type];
    [_foregroundNode addChild:platformNode];
  }
}

There’s a lot going on here, but it’s simple stuff. You load the Platforms dictionary from levelData and then loop through its Positions array. For each item in the array, you load the relevant pattern and instantiate PlatformNodes of the correct type at the specified (x, y) positions. You add all the platform nodes to the foreground node, where all the game objects belong.

Build and run. You’ll see a set of three platforms aligned in the scene, which is the “Triple” pattern described in Level01.plist.

16-Level01Platforms

Now do the same for the stars. Inside MyScene.m, replace the following line in initWithSize::

// Add a star
StarNode *star = [self createStarAtPosition:CGPointMake(160, 220) ofType:STAR_SPECIAL];
[_foregroundNode addChild:star];

With this code:

// Add the stars
NSDictionary *stars = levelData[@"Stars"];
NSDictionary *starPatterns = stars[@"Patterns"];
NSArray *starPositions = stars[@"Positions"];
for (NSDictionary *starPosition in starPositions) {
  CGFloat patternX = [starPosition[@"x"] floatValue];
  CGFloat patternY = [starPosition[@"y"] floatValue];
  NSString *pattern = starPosition[@"pattern"];

  // Look up the pattern
  NSArray *starPattern = starPatterns[pattern];
  for (NSDictionary *starPoint in starPattern) {
    CGFloat x = [starPoint[@"x"] floatValue];
    CGFloat y = [starPoint[@"y"] floatValue];
    StarType type = [starPoint[@"type"] intValue];

    StarNode *starNode = [self createStarAtPosition:CGPointMake(x + patternX, y + patternY) ofType:type];
    [_foregroundNode addChild:starNode];
  }
}

This is exactly what you did to create the platforms, but this time you create stars for the items in the Stars dictionary.

Build and run. This is starting to look like a real game!

17-Level01Stars

The Midground Layer

Graphically, there’s just one more thing to add to give the game a greater illusion of depth, and that’s the midground layer. This is the node that’s going to contain decorative graphics to bring the game to life.

Add the following method to MyScene.m:

- (SKNode *)createMidgroundNode
{
  // Create the node
  SKNode *midgroundNode = [SKNode node];

  // 1
  // Add some branches to the midground
  for (int i=0; i<10; i++) {
    NSString *spriteName;
    // 2
    int r = arc4random() % 2;
    if (r > 0) {
      spriteName = @"BranchRight";
    } else {
      spriteName = @"BranchLeft";
    }
    // 3
    SKSpriteNode *branchNode = [SKSpriteNode spriteNodeWithImageNamed:spriteName];
    branchNode.position = CGPointMake(160.0f, 500.0f * i);
    [midgroundNode addChild:branchNode];
  }

  // Return the completed background node
  return midgroundNode;	
}

Take a closer look at this code:

  1. You add ten branches to midgroundNode, spaced evenly throughout the level.
  2. There are two different branch images, one showing branches coming in from the left of the screen and the other from the right. Here you grab one randomly.
  3. You space the branches at 500-point intervals on the y-axis of the midground node.

Now add the midground node to your scene by inserting the following code into initWithSize:, immediately after the line that adds the background node:

// Midground
_midgroundNode = [self createMidgroundNode];
[self addChild:_midgroundNode];

Build and run. Look! It’s a branch (of sorts) and maybe some pink butterflies!

18-MidgroundNode

Note: The pink butterflies will only appear if the randomly-chosen branch is the one coming from the right side of the screen. The other branch image does not include the butterflies.

Tap to start the game and you will see the player sprite shoot up the screen. However, even as the Uber Jumper ascends, the game world remains still.

19-MidgroundNodeRun

The background, midground and foreground layers should all move with the player node to keep the player sprite in the center of the screen. You’re going to sort that out next.

Toby Stephens

Contributors

Toby Stephens

Author

Over 300 content creators. Join our team.