How to Make a Game Like Jetpack Joyride using LevelHelper and SpriteHelper [Corona Edition] – Part 1

Bogdan Vladu

This is a post by special contributor Bogdan Vladu, an iOS application developer and aspiring game developer living in Bucharest, Romania.

Learn how to create a game like Jetpack Joyride with LevelHelper and SpriteHelper!

Learn how to create a game like Jetpack Joyride with LevelHelper and SpriteHelper!

In this tutorial series, we will create a game similar to Jetpack Joyride using Corona SDK. (Prefer Cocos2D? Check out the Cocos2D version of this tutorial!)

If you haven’t played Jetpack Joyride yet, you should check it out – it’s an incredibly polished and fun game, and best of all it’s free! :]

You could make this game with Corona SDK alone, but it would take a lot of time. To make things simpler, we’re going to use two tools written by yours truly – LevelHelper and SpriteHelper.

If you aren’t familiar with these tools, here’s a quick synopsis:

  • LevelHelper is a tool that makes creating levels much easier. You literally drag and drop sprites onto the scene!
  • SpriteHelper is a tool that creates the sprite sheets and physics shapes for your games quickly and easily.

This is going to be a complex game, and we have a lot to do, so this series will be spread over four parts. In this first part, we’ll first spend some time setting up LevelHelper. Then we’ll create a basic level with a continuous scrolling parallax, and learn how to use SpriteHelper to add and modify our art.

By the end of this series, not only will you have earned valuable experience with these tools – you will have an exciting, sophisticated game to play!

Getting Started

To get started, you just need to download several things:

Installing the LevelHelper Template

After you have download the template file, unzip the file (if its not already unzipped by Safari) and rename the new folder from “CoronaSDK LevelHelper Template” to RocketMouse.

w00t you’ve installed the template! Now let’s try it out. Run the template in Corona, and you will see something like this:

Examining the Code

Open up main.lua, and you’ll see that there is very little code:

local ui = require ("ui")
local physics = require("physics")
local fps = require("fps");
physics.start()
--comment next line to disable debug drawing
physics.setDrawMode( "hybrid" ) 
display.setStatusBar( display.HiddenStatusBar )
require "LevelHelperLoader"
 
loader = LevelHelperLoader:initWithContentOfFile("testLevel.plhs")
loader:instantiateObjects(physics)
loader:createPhysicBoundaries(physics)

First we create and start the physics engine. We also enable debug draw for the physic engine in order to see how shapes are simulating.

We then load our LevelHelper level – let’s go over the lines that do this in detail.

  • require “LevelHelperLoader”: This will tell lua that we need to use the class provided in that file and it should look at it.
  • loader = LevelHelperLoader:initWithContentOfFile(“testLevel.plhs”): This line will load our LevelHelperLoader instance in a variable called “loader” with the content of the level file specified.
  • loader:instantiateObjects(physics): This line will actually load the level, using physics into Corona SDK engine.
  • loader:createPhysicBoundaries(physics): This line creates the physic boundary (invisible screen edge to not let the dynamic bodies get out of view), but in this tutorial we don’t care about this and you can just remove it.

Next open up config.lua and take a look:

application = 
{
	content = 
	{ 
		fps = 60,
		width = 320,
		height = 480, 
		scale = "letterbox"
	},
 
	LevelHelperSettings = 
	{
		imagesSubfolder = "Images",
		levelsSubfolder = "Levels",
		directorGroup = nil
	}
}

The first “content” part is the generic Corona SDK settings, determining how the view is set up.

The second “LevelHelperSettings” is the setup for the LevelHelperLoader class. It tells the loader class where it should read the image and level files.

The last line “directorGroup” is the group inside which you want to put all sprites from the level. We’ll talk more about this soon.

Take some time to look through main.lua and make sure you understand the basic idea of what’s going on so far. We’ll build up from here! :]

Creating a LevelHelper Project

Now that the project setup is complete, we can finally start creating our level with LevelHelper!

Beginning with version 1.4, LevelHelper will keep things organized in projects. This means level files are part of the project rather than individual files, as they used to be.

So let’s create a new project with LevelHelper. Open it up and go to File\New Project:

A new sheet window will appear. In the Project Name field, enter “RocketMouse,” the name of our project. Leave the Screen Size as the default, “iPhone Landscape (480×320).”

Note: When you want to create a game for all models of iPhone and iPad, you generally want to choose iPhone with Landscape or Portrait orientation. LevelHelper will automatically use SD on iPhone2G/3G/3GS and HD on iPhone4/4S and iPad1/iPad2.

If you want to create a game only for iPad, use the iPad template and inside SpriteHelper, unselect “Save SD” when creating the sprite sheets.

For iPad there is also an option to not stretch graphics. That won’t work for this tutorial, because we will be using continuous scrolling parallaxes.

Under “SpriteHelper scenes and image files directory,” choose the “Images” folder from your CoronaSDK project folder, and click Open.

Under “Path to source code,” select the RocketMouse folder (the main CoronaSDK project folder). This is the folder where LevelHelper will generate the code needed to load the level in CoronaSDK. Click Open.

This setting tells LevelHelper where to automatically generate code, when needed.

Under “Engine” select “Corona SDK”. Here you are selecting what code you want LevelHelper to automatically generate for you. For this tutorial, we will use Corona SDK, but as you can see LevelHelper supports several other engines/configurations as well!

Make sure that the “Auto generate code when needed” option is selected. This tells LevelHelper to generate the code when there’s been an update to the code, or after you’ve added new tags to your project.

Under “LevelHelper scenes directory,” choose the Levels folder, and click Open.

The final Project setting window should look something like this:

Note: Next to every major feature inside LevelHelper there is a “?” button. Click it to view a movie explaining that feature.

When you’re done, click the Create New Project button. A new window will appear asking you to save the project to a file.

Save the new file in the same folder as the Corona project (RocketMouse.lhproject).

Now the LevelHelper window should look something like this:

But we have no image, no nothing! Time to start adding our art.

Adding Art to Our LevelHelper Project

To add our art, we need to use SpriteHelper, so go ahead and open it up.

Now navigate to where you saved the art pack for this tutorial. Select the particular files shown in the screenshot below (not all of them, just the ones shown), and drag them inside SpriteHelper.

In the Sheet Editor window on the right, uncheck the Crop option. Crop removes transparent space on sprites, but for some of our animations the sprites use transparency for placement so we don’t want the transparency modified.

For animations, it’s almost always best to uncheck Crop (to be renamed “Trim” in the next update).

Now click the Pack Sprites button at the bottom of the Sheet Editor window.

The resulting scene should look similar to this (sprites may be packed differently):

Save the scene inside the Images folder inside the Resource folder. Go to File\Save As.

In the Save dialogue window, name the scene “objects” and click Save.

If you look inside the LevelHelper window now, you’ll see that the art has automatically been added for you.

LevelHelper keeps track of all the changes inside the Levels and Images folders, just as we told it to when we created the project. Every time you add, remove or modify a file inside those folders, LevelHelper will automatically update its content.

Note: If you do not see the art in LevelHelper, click the bar above project settings and make sure the path to the Images folder is correct, and that the path does not contain any spaces.

Creating a Basic Level

Let’s start by creating a level with a scrolling floor and wallpaper background.

We first want to create a continuous scrolling parallax that will move from right to left. To do this, let’s decide how big our parallax will be. You can make it as big as you want.

Let’s make our game world the size of 8 screen sizes. Click the Game World Size button.

In the Width field, enter 3840. This is 8 multiplied by 480 (the width of the iPhone screen).

Now let’s create the background. Drag “bg” sprite into the level, and place it right at the beginning of the first screen. The first screen should be on the left side, and is demarcated by a red border.

Now we’re going to duplicate the sprite so that it covers all of our screens. With the background sprite selected, set the clone direction as in the image below so that you clone in the right direction.

Then click the green + sign. This is the clone button. (Alternatively, you could press Command+D). Continue pressing this button until the background sprite covers all sections of all eight screens. Do not go any further.

Note: You can scroll the level in LevelHelper by holding control as you drag the level, and you can zoom in and out by holding the option key as you scroll the mouse wheel.

It should look like this:

Let’s add these images to a continuous scrolling parallax. Navigate to the Parallax tab (the one that says “P”) and press the New Parallax button.

With the parallax selected, check the Continuous Scrolling option. Now select all the background sprites in the level, and click the Add Selected Scene Sprite(s) button in the parallax section.

There are still some adjustments to make to our continuous scrolling parallax. First, set the Speed preliminarily to 2.5 (we will change this later to match the movement speed of the mouse). Make sure that the Direction is set to Right to Left.

Now select all sprites in the parallax list and set the Movement Ratio to “1” and “0.” This ratio and the speed determine the rate at which the sprites will move through the parallax.

In this case, the sprites will move at the rate of 1*2.5 (ratio*speed). If we want other sprites to move at a different rate, we can modify the ratio accordingly (e.g. 0.4*2.5).

If you run Scene Tester right now (download and install it if you need to), it will move the continuous parallax, continuously!

Let’s save this level and run it in our Corona project. Inside LevelHelper, go to File\Save Level As.

In dialogue box, enter “level01″ and click Save.

By saving the level, we caused LevelHelper to update the Levels section. Navigate to the Sprites section and then go the Levels to see the level file. By double clicking on a level, you can open that level inside LevelHelper.

Now navigate to main.lua. Open it and look for where in the code the level is loaded.

Replace the level name in this section of code with your level name, in this case “level01.” The new line of code should read:

loader = LevelHelperLoader:initWithContentOfFile("level01.plhs")

Now run the project in the Corona Simulator.

That’s all it takes to run your level – pretty cool eh?

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 And Align 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 blue or purple 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 all sprites have physics shapes on them.

Previously (in LevelHelper 1.3), we had to disable this behavior for each sprite inside LevelHelper. Now we can make it so that what we update in the SpriteHelper scene will also be updated in the level file.

If for our sprites we have “Handled by SpriteHelper” selected each time we do a change in the corresponding SpriteHelper document, the change will be immediately visible in the level. We no longer need to reopen that level or modify the previously added sprites in the level.

Fortunately “Handled By SpriteHelper” is the default setting, so we shouldn’t need to do anything to enable it. Let’s open up the SpriteHelper document and modify the settings on the sprites.

We can do this by opening SpriteHelper and then opening that document, but there’s an easier way:

I will do this process the long way so that you learn everything. In the list of sprites on the left side of the LevelHelper interface, select a sprite and Control-Click (or right click) on it. Now select Show SpriteHelper Scene.

This will take you to the SpriteHelper Scenes section and select the corresponding scene file for you. (this is very helpful, because sometimes it’s hard to remember from which scene a sprite came.)

Now Control-Click (or right click) on the scene and select “Open In SpriteHelper.”

This will open the needed scene in SpriteHelper, where we can select the sprite we want to modify and select “No Physics” under the Physics tab.

Make sure to save the scene when you’re done.

Now if you go back to LevelHelper, you’ll see that the physics shapes have disappeared. Save the level as new one by pressing Command-Shift-S. Give it the name “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 and 0.

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

Notice that the shape objects for the dog and cat sprites are basic quads.

Let’s make the shapes trace the dog and cat, so that they move with the correct physic behavior.

To do this, open the SpriteHelper scene as we did in the previous step by selecting the dog sprite and navigating to the correct scene file.

Inside SpriteHelper, select the dog sprite, navigate to the Physics section and click the Create Shape button.

Now click and trace the shape around the dog. Click Finish Shape when you are done.

Notes:

In SpriteHelper you can pan the view with 2 finger on the trackpad and move, or by holding Option key and drag with the mouse.
To zoom in or out you can use the popular pinch gesture on the trackpad or the mouse wheel.

Note: You can change a shape by clicking the “Edit Shape” button and then dragging the points as needed. You can add new points by clicking on the shape line. You can remove points by holding the Control key and clicking on a point.

Repeat the process for the cat. When you’re done, make sure to save the scene.

Run in the Corona simulator. Now your level is looking a lot more interesting!

Basic scrolling level made with LevelHelper

Where to Go From Here?

So now we have our basic level! But most significantly – we’ve learned a great deal about navigating within and between LevelHelper and SpriteHelper, and adding and modifying that all-important art.

You can download the entire project up to this point here.

In Part Two, we’ll learn how to add and work with animations and sensors. We’ll also create our player, and begin working with tags – the first step in implementing collisions between sprites. In other words, the action begins!

Things will get even more interesting in the third and fourth parts. Besides fully implementing collisions, we’ll animate takeoffs and landings, learn how to kill the player and restart the game, create and display a scoring system, and add plenty of other cool features.

In other words, you definitely want to stay tuned! Getting through the basics is always challenging, so if you’ve made it this far, congratulations. In the meantime, I look forward to reading and responding to your questions, comments and suggestions in the LevelHelper forum and in the forum below.


This is a post by special contributor Bogdan Vladu, an iOS application developer and aspiring game developer living in Bucharest, Romania.

User Comments

13 Comments

  • Thanks for a great tutorial.My scrolling is quite jumpy, do you have a suggestion for making it more smooth? I have tried changing the framerate but it didn't really help. I run the game in the simulator I haven't seen if it is more smooth on a device.
    Camilla
  • Its more smooth on the device, faster speed = jumpiness - smaller speed = good

    The problem is corona - it is a bug (there is a post on the corona official forum saying the id of the bug).
    The bug has been submitted and acknowledge as a bug and now we can just wait for the fix.
    vladubogdan
  • Hi there, the latest version of Level Helper does not seem to work with this tutorial.

    When I try to make any changes to an existing level file or when I create a new level and save it in level helper. I only ever get a blank screen in the iphone simulator, the simulator fails to load the levels!, If i replace the level with a level created in a older version of Level Helper. It works... I love these tutorials and this is really holding me back :(

    Does anyone else have this same problem?

    Hope someone can help?

    Chris
    chris07867
  • Chris, you need to update supporting code. Latest version uses an optimized level file and so the reading of the level has changed. Remove all LH supporting code from your project.

    All files starting with LH....lua
    LevelHelperLoader.lua

    then use LH - Supporting Code tab and download latest version.

    If on lion or mountain lion you may need to follow this guide also
    http://www.levelhelper.org/app/document ... allSVN.htm


    After you have downloaded the latest revision - do a File -> Generate Code -> Corona - choose your project.

    Now to load the level you just do this


    require("LevelHelper.LevelHelperLoader")
    loader = LevelHelperLoader:initWithContentOfFile("basicLevel.plhs")
    loader:instantiateSprites()
    vladubogdan
  • First of all I would like thank you for providing such an useful tutorial online :)

    I have a question, recently I've been working on something like endless runner games, but I'm stucked on level design part. Does anyone of you know how they actually create the level in Temple Run, Jetpack Joyride, Agent Dash, or Subway Surfer? Level design as in those obstacles, events, power-ups, coins... how they position them in the level? Do they really use level editor to do that or they actually generate dynamically (using codes)?
    birdkingz
  • I think they use a level editor to generate parts or levels and then via code put together those parts in order to create something randomly.
    vladubogdan
  • I just downloaded the latest version of levelhelper and spritehelper, and trying to get started with the tutorial. However, when I use the objects in level helper that were prepared onto a sprite sheet with spritehelper, even though I have the layout in levelhelper set to iphone 3840x320, my background sprite looks like it is only 1/2 the height of the background. Not sure what could be wrong. Did I miss a scaling step somewhere?
    fullthrottle
  • Oh,

    Now spritehelper by defaults generate sheets with ipad retina also

    so your original image is

    image.png (sd 4x smaller then original)
    image-hd.png (hd 2x smaller then original)
    image-ipadhd.png (ipad-hd - original size)

    So the issue you have is that the original art for this tutorial was hd compatible only (so its not ipad retina compatible)

    As such when you save in spritehelper - choose iPhone only and not ipad and iphone from the save dialogue

    Or you can also rescale the original art 2x bigger in order to support ipad retina also.
    vladubogdan
  • Okay, thank you for the response; that was the problem. At least I was now able to bring the sprites in to LevelHelper and clone the bg image onto the grid.

    I then spent a while figuring out where the parallax option now is in the current version; it has been moved since the tutorial was posted.

    I then tried to download the LevelHelper document using the link specified in the tutorial, but that link is broken. So, I went and watched the Level Helper video at the website and realized I needed to install XCode and some command line tools before I could compile the levelhelper api classes. Downloaded and installed the tools, and then was finally able to generate the LevelHelper folder and all the classes in my project (used the latest build for the compile). I then put this at the top of my main lua and tried to compile with Corona Simulator:
    require("LevelHelper.LevelHelperLoader")

    which is exactly where the file has been generated. However, when I compile the debugger gives me this:
    module 'LevelHelperLoader' not found:resource (LevelHelperLoader.lu) does not exist in archive
    no field package.preload['LevelHelperLoader']
    no file '/Users/gdotzlaw/Documents/Corona Projects/JetPack Joyride/LevelHelperLoader.lua'
    no file '/Applications/CoronaSDK//Corona Simulator.app/Contents/Resources/LevelHelperLoader.lua'
    no file './LevelHelperLoader.dylib'
    no file '/Applications/CoronaSDK//Corona Simulator.app/Contents/Resources/LevelHelperLoader.dylib'

    At this point, I spent about 2 hours trying to get the first page of this tutorial working. Hate to think what I will run into on subsequent pages. Maybe its time this tutorial was updated? It appears to be out of date and quite frustrating. Not making a very good impression for SpriteHelper or LevelHelper, which I am confident must be decent tools.
    fullthrottle
  • I suggest you first do the Step by Step guide from under Documentation menu of LevelHelper. That will put you up to speed.
    Also Parallax section is exactly where it was before :)
    You mention corona debugger - i never used a debugger in the tutorial - so what are you talking about? Please remove any debug code from your app.
    First make sure your app compiles and then do debugging if you really need it. Debugging is for when your app is crashing or it behaves different then you expect.

    Also it may be that right now you have 2 versions of LevelHelper supporting code in your project folder. Remove all LH lua files and generate clean.
    Code should only be inside LevelHelper folder.

    Your errors tell me that LevelHelperLoader.lua is not present in your project folder. So you maybe generate it in another location or not at all.
    So make sure you have LevelHelper folder in your project folder and that it contains a bunch of folder with other lua files and LevelHelperLoader.lua

    Dont lose time investigating (although this is what teaches the best) write here and i will help you out.
    vladubogdan
  • Thanks for your patience.

    I got it scrolling now, although I had to turn the speed up to 50 with a movement ratio of 1 to get it scrolling decently on an iphone landscape layout in the simulator. There is however a thin black line between each bg image as they scroll by. I'm wondering if maybe I didn't trim the sprite properly before bringing it into levelhelper?

    Not sure what the problem was originally, but I just started over and tried it a second time with a new project file. Perhaps you were right, I had some other LH file in there that was causing the problem.

    I meant simulator output, not debugger. Sorry about that.

    Thanks for the help.
    fullthrottle
  • To remove that thin black line - select your background sprites that are in the parallax and apply a small 1.03 1.04 scale on x.
    Or zoom in on the edges and make sure the sprites overlap just a little bit.
    vladubogdan
  • HI, as a new follower of your tuto, I can't find the Corona SDK template for LevelHelper (the link goes nowhere). I searched elsewhere, but no solution found, do you know where I can find it?

    Thanks

    Vic
    Vicolapata

Other Items of Interest

Ray's Monthly Newsletter

Sign up to receive a monthly newsletter with my favorite dev links, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

Vote for Our Next Tutorial!

Every week, we alternate between Gaming and Non-Gaming tutorial votes. This week: Non-Gaming!

    Loading ... Loading ...

Last week's winner: How to Make a Simple 2D Game with Metal.

Suggest a Tutorial - Past Results

Hang Out With Us!

Every month, we have a free live Tech Talk - come hang out with us!


Coming up in October: Xcode 6 Tips and Tricks!

Sign Up - October

Our Books

Our Team

Tutorial Team

... 52 total!

Update Team

  • Zouhair Mahieddine

... 14 total!

Editorial Team

... 22 total!

Code Team

  • Orta Therox

... 3 total!

Subject Matter Experts

  • Richard Casey

... 4 total!