How To Use SpriteHelper and LevelHelper Tutorial

If you’ve ever manually laid out a level in Cocos2D, you know how painful it can be. Without tool support, you’ll find yourself guessing a position, testing to see how it looks, tweaking and testing again, and repeating over and over. Well, thanks to some tools that are starting to become available, life has become […] By .

Leave a rating/review
Save for later

Create a simple game with SpriteHelper and LevelHelper!

Create a simple game with SpriteHelper and LevelHelper!

Create a simple game with SpriteHelper and LevelHelper!

If you’ve ever manually laid out a level in Cocos2D, you know how painful it can be.

Without tool support, you’ll find yourself guessing a position, testing to see how it looks, tweaking and testing again, and repeating over and over.

Well, thanks to some tools that are starting to become available, life has become a lot easier!

In this tutorial, I’m going to show you how to use two of these tools (SpriteHelper and LevelHelper) to create a simple platformer game with Cocos2D and Box2D.

To go through this tutorial, you need a copy of LevelHelper and SpriteHelper. However, if you don’t have a copy you might like to just read this tutorial anyway to learn about the tools – and check out my personal review at the end.

You should also be familiar with the basics of using Cocos2D and Box2D. If you are new to Cocos2D or Box2D, please review some of the other other Cocos2D and Box2D tutorials on this site first.

Full disclosure: I have received a free review copy of LevelHelper and SpriteHelper, and these tools are advertised on my site. However, my review and comments are my honest opinions as a game developer.

Game Overview

In this tutorial, we’re going to make a very basic game where you’re a little angel that is just trying to get from one end of the level to the other without falling in any pits.

This will demonstrate the basics of using LevelHelper and SpriteHelper and creating a scrolling level with player movement, and in future tutorials we’ll add on some extra features.

To make the game, we’re going to use some art made by my lovely wife, so go ahead and download the resources for this project that she made us (along with some sound effects made by yours truly!)

This game is going to be called Raycast, because later on we’ll be integrating Box2D Raycasting into the game, and also I think the name is just totally awesome (and no I’m not biased at all!) ;]

Getting Started

OK, let’s get started!

Start up Xcode, go to File\New\New Project, choose iOS\cocos2d\cocos2d_box2d, and click Next. Name the new project Raycast, click Next, choose a folder to save your project in, and click Create.

Update 3/1/2012: Instead of using the cocos2d_box2d template, you should use the LevelHelper Xcode 4 template. Follow the instructions in this tutorial to download and install the template. Name it Raycast and continue along.

From the resources for this project that you downloaded, drag the Fonts and Sounds folders into your project. Verify that “Copy items into destination group’s folder (if needed)” is selected, and click Finish.

Right now the project contains some sample Box2D code in HelloWorldLayer.h and Let’s remove this and create a new layer to get to a blank slate.

Control-click on HelloWorldLayer.h and, click Delete, and click Delete again.

Next go to File\New\New File, choose iOS\Cocoa Touch\Objective-C class, and click Next. Enter NSObject for Subclass of, click Next, name the new class, and click Save.

Replace ActionLayer.h with the following:

#import "cocos2d.h"

@interface ActionLayer : CCLayer {

+ (id)scene;


This declares a subclass of CCLayer, and a static method to create a new CCScene.

Switch to and replace it with the following:

#import "ActionLayer.h"

@implementation ActionLayer

+ (id)scene {
    CCScene *scene = [CCScene node];    

    ActionLayer *layer = [ActionLayer node];
    [scene addChild:layer];    
    return scene;


This implements the static method to create a new default CCScene and add the layer as the only child.

Finally, switch to and make one final set of changes:

// Replace #import "HelloWorldLayer.h" with this:
#import "ActionLayer.h"

// Replace call to runWithScene with this:
[[CCDirector sharedDirector] runWithScene: [ActionLayer scene]];

Compile and run, and you should have a blank scene that will serve as our starting point!

A blank scene with Cocos2D

SpriteHelper and Sprite Sheet Generation

SpriteHelper is a tool that contains some aspects of Texture Packer (sprite sheet generation) and Physics Editor (physics shape definitions).

If you compare SpriteHelper’s feature set to Texture Packer and Physics Editor, Texture Packer and Physics Editor are easily superior due to many neat features such as dithering, command line support, built-in Cocos2D integration, auto-shape tracing, and more.

However, SpriteHelper truly shines with its integration with LevelHelper. Once you create the sprite sheets and shapes with SpriteHelper, you can then use LevelEditor to do scene layout, something that would be a manual process with the above tools.

So let’s try it out! Start up SpriteHelper and the following window will appear:

Default screen in SpriteHelper

Open up Finder and navigate to where you downloaded the resources for this project, and drag all of the images inside the Raw directory into the gridded area inside SpriteHelper.

The images will appear all on top of each other. To get SpriteHelper to auto-layout the sprites, set the following in the top toolbar:

  • Make sure Crop is unchecked. If it was checked, it would remove transparent space around sprites, but we don’t want this because the transparent space is actually important for our animations.
  • Make sure Save SD is checked. Our art is HD, so checking this will automatically create a copy scaled by 50% for the SD version when we go to save.
  • Make sure NPOT is checked. This will save the sprite sheets as a non power of two (NPOT) texture. This saves texture memory on the iPad, iPhone 4, and iPod Touch 4th, which can read non-power of two textures without having to expand them to the closest power of two like older devices. Note you have to set CC_TEXTURE_NPOT_SUPPORT in ccConfig.h to enable this in Cocos2D.

Finally, click Pack Sprites and SpriteHelper will automatically layout the sprites:

Packing sprites with SpriteHelper

At this point you’re done with the sprite sheet generation part of SpriteHelper – let’s move on to the physics shape definition aspect!

SpriteHelper and Physics Shape Definitions

For each sprite you’ve added into SpriteHelper, you can configure the physics body that maps to the sprite.

By default, it maps a rectangular body that matches to the bounds of the sprite. You can make the rectangle smaller with the “Shape Border” setting, set it to a circle with the “Is Circle” setting, or create your own custom polygon with the “Create Shape” buttons.

You can also set other physics properties such as:

  • Is Sensor: If this is true, the object can detect collisions but can move through other objects.
  • Shape type: Static means “does not move”, kinematic means “moved by setting velocity, does not respond to forces or collisions”, and dynamic means “normal movement via Box2D”. Usually you’ll use static for ground objects, and dynamic for most everything else.
  • Density: How hard the body is to move
  • Friction: How slippery the body is
  • Restitution: How bouncy the body is
  • Mask Bit: A bitfield indicating what categories the body collides with.
  • Category Bit: A bitfield indicating the categories the body belongs to.
  • Group Index: Any bodies with the same group index always collide (if the index is positive) or never collide (if the index is negative), regardless of category/mask settings. Personally I use mask/category bits more often over group indices, as I find them easier to work with.

I find setting the mask bits and category bits is difficult unless you draw out the categories on paper first. Here’s the category and masks we’re going to need for this game (note categories must all be powers of 2 since they are stored in a bitfield):

  • Laser: Category 1. Should be able to collide with heros (2), so its mask bit is 2.
  • Hero: Category 2. Should be able to collide with lasers (1) and clouds (4), so its mask bit is 5.
  • Cloud: Category 4. Should be able to collide with heros (2) and monsters (8), so its mask is 10.
  • Monster: Category 8. Should be able to collide with clouds (4), so its mask bit is 4.

With this all set, setting up our shapes and properties will be easy! Go through each shape and set up the settings as specified below.


LevelHelper Monster Settings

Here we set the body as dynamic, with a circle shape with a slight border so it better matches the monster’s shape.


LevelHelper Cloud Settings

Here we set the body as static (since it does not move), with a square shape with a large border to match the cloud better. We also set the friction up a bit so the hero doesn’t slide around on it too much.


LevelHelper Laser Settings

This time we set the body as kinematic, because we will be moving the laser by setting the velocity manually and don’t want any other forces (such as gravity) to interfere with it. We also set it up as a sensor so it doesn’t get stopped by any other bodies.

Hero (select all 4 sprites at once)

LevelHelper Hero Settings

This is a dynamic body with a shape border to better fit the main body of the character. Friction is set high to avoid sliding, and bounciness is decreased. We also set the body to fixed rotation, because falling on your face isn’t very angelic! :]


You’re finally done with SpriteHelper! Go to File\Save, click Yes if the popup appears, and save it somewhere on your drive as “Sprites” (SpriteHelper will add the .png extension automatically). Another Save As dialog will appear – enter “Sprites” again (SpriteHelper will add the .pshs extension automatically).

If you didn’t have LevelHelper, you could use SpriteHelper to generate some code that would let you use the generated sprite sheet and physics data in your game, but we do have LevelHelper, so let’s move on to that!