How to Make a Game Like Jetpack Joyride using LevelHelper, SpriteHelper [Cocos2D 2.X edition] – Part 1

This is a post by special contributor Bogdan Vladu, an iOS application developer and aspiring game developer living in Bucharest, Romania. In this tutorial series, we will create a game similar to Jetpack Joyride using latest Cocos2D and Box2D. (Prefer Corona? Check out the Corona version of this tutorial!) If you haven’t played Jetpack Joyride […] By .

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 4 of this article. Click here to view the first page.

Creating the Full Level

Let’s go back to LevelHelper and add the remaining art so that we have a final level to play with.

Drag the small bookshelf onto the main screen. Drag it around until you are satisfied with its placement relative to the background sprite.

With the bookshelf sprite selected in the level, click the Clone Tool button in order to make multiple clones of this sprite.

Set the number of clones to 7, and set offset X to 500 and offset Y to 0.

You should see a series of outlines indicating how the sprites will be set in the level. Click the “Make Clones” button when you are satisfied.

Note: Right clicking on any stepper button will reset the associated field to the default value.

Now let’s repeat the process to add the rest of the art.

Add in the big bookshelf, the cat, the dog and the window sprites and place them according to your preferences.

I’ve opted to put the dog under each window, because dogs like to look out the window. I’ve placed the cat next to each mouse hole, for obvious reasons. And I’ve placed the bookshelves randomly in the level.

My final level looks like this:

If you enable the Show Polygon Shapes option inside LevelHelper, you’ll see that the sprites have no physic shapes on them.

If your sprites have “Handled by SpriteHelper” selected, each time you do a change in the corresponding SpriteHelper document, the change will be immediately visible in the level.

Fortunately “Handled By SpriteHelper” is the default setting, so you shouldn’t need to do anything to enable it. Now open the SpriteHelper document and modify the settings for the sprites. You could do this by opening SpriteHelper and then opening that document, but there’s an easier way: simply click the “Edit” button.

Note: The Physice Properties section with the “Edit” button might not be visible if you are at the top of the Properties Navigator. The Properties Navigator has a lot of sections – so scroll down a bit to get to the Physics Properties section.

This will open the needed scene in SpriteHelper, where you can select the sprite you want to modify the physics properties for.

With the dog sprite selected, go to the Physics tab. Press on the “Create New Auto Traced Shape”. Select Static as the body type. Double click on the fixture name to rename it and further optimize the shape by moving the “Optimize Fixture” slider.

That’s all there is to it. Isn’t that cool?

Repeat the process for the cat sprite.

Save the scene when you’re done. (press “Command-S”)

Now if you go back to LevelHelper, you’ll see that the level has been updated and the cat and dog sprites have physics shapes. Save the level as a new level by pressing Command-Shift-S. Name it “level02.”

If you run Scene Tester now (press “Test Level” button), you’ll see that only the background sprite will move.

Let’s add the other sprites to the parallax. To do this, first select all sprites except the background sprites that have already been added to the parallax.

Now go to the Parallax tab, select your parallax and add the selected sprites.

Select the sprites from the list of sprites in the parallax, and set the Movement Ratio to 1.

If you run Scene Tester now, all the sprites in the scene should move at the same speed continuously.

Lets create a background sheet inside the SpriteHelper document. Each sheet represent a batch node so this will make it easier for you to sort sprites by z order. You will understand more in a minute.

With your SpriteHelper document open, click on the + button to create a new sheet and drag all images from the “background” folder on to it.

Rename the new sheet to “background” and then save it (Command-S).

If you now look in LevelHelper, you will see that your SpriteHelper document has 2 sheets. (Reload the document if you don’t see the two sheets.)

Drag the “window_background” sprite on to your scene and place it somewhere above the other sprites. Set its z order to -1

Drag the “window_foreground” sprite on top of the “window_background” sprite. Leave the z order at 0.

With both the new sprites selected, clone them until the end of the 8 screens.

Add all the new sprites to the parallax. Set the ratio to 0.4 for the “background” sprites and 0.7 for the “foreground” sprites.

Now select all the new sprites and drag them on top of the windows. As you can see all the new sprites are above the other sprites:

But we need them to be behind the existing sprites. So, select the “background” batch node from the Level Navigator and change its z order to -1.

Save the level! If you run Scene Tester now you will see that the outside sprites move at a slower rate, giving a feeling of depth.

Now let’s try it out in your app! Switch back to Xcode, control-click on your Resources\Levels folder, select Add Files to RocketMouse. Add the new level file “level02.plhs”.

Also right-click on the Resource\Images folder and add the new sheet images.

Your new Resource folder should look something like this:

Change the level loader code to set “level02” as the argument.

lh = [[LevelHelperLoader alloc] initWithContentOfFile:@"level02"];

Compile and run. Your level is looking a lot more interesting!

Basic scrolling level made with LevelHelper

Update physics

In order for the physic shapes to be synchronized with the sprites, replace the current update: implementation in HelloWorldLayer.mm with this:

-(void) update:(ccTime)dt {
	//It is recommended that a fixed time step is used with Box2D for stability
	//of the simulation, however, we are using a variable time step here.
	//You need to make an informed choice, the following URL is useful
	//http://gafferongames.com/game-physics/fix-your-timestep/
	
	int32 velocityIterations = 8;
	int32 positionIterations = 1;
	
	// Instruct the world to perform a single step of simulation. It is
	// generally best to keep the time step and iterations fixed.
	world->Step(dt, velocityIterations, positionIterations);
	
    //Iterate over the bodies in the physics world
    for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
    {
        if (b->GetUserData() != NULL)
        {
            //Synchronize the AtlasSprites position and rotation with the corresponding body
            LHSprite *myActor = (LHSprite*)b->GetUserData();
            
            if(myActor != 0)
            {
                //THIS IS VERY IMPORTANT - GETTING THE POSITION FROM BOX2D TO COCOS2D
                myActor.position = [LevelHelperLoader metersToPoints:b->GetPosition()];
                myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
            }
            
        }
    }
}