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

In this part of the series, you’ll make your game fully capable of handling collisions. In other words, by the end of this part you’ll be able to reward and kill the mouse! By .

Leave a rating/review
Save for later
Share

Create a game like Jetpack Joyride with latest LevelHelper and SpriteHelper!

Create a game like Jetpack Joyride with latest LevelHelper and SpriteHelper!

Welcome back to our Jetpack Joyride tutorial series! In this tutorial series, you are making a game similar to Jetpack Joyride using Cocos2D and Box2D, and the LevelHelper and SpriteHelper tools.

So far, you’ve got a mouse that can use his jetpack to fly through a scrolling level, complete with animations and endless scrolling. Check out how to do it in Part One and Part Two.

I hope you enjoyed the first two parts, but, psst… Part Three is where we get to the really fun stuff!

In this part of the series, you’ll make your game fully capable of handling collisions.

In other words, by the end of this part you’ll be able to reward and kill the mouse! :]

You’ll also add sounds, more sophisticated animations, and you’ll iron-out some problems with game play.

So what are you waiting for? It’s time to give your mouse the ride of his life!

Getting Started

To continue with this part of the tutorial, first make sure that you have the complete project from Part Two of the tutorial, available here. You will also need to download this sound pack, which you will be using later on.

Open your project in LevelHelper and open the last level file – level03.

Implementing Collisions: Overview

The game has a flying mouse and shooting lasers (with the help of animations), and it also has coins for the player to collect. However, if you run into the coins or lasers nothing happens – so it’s time to add some gameplay to handle those collisions!

Before you do so, however, let’s take a look at how things are currently set up.

If you open the RocketMouseAssets SpriteHelper scene and select the coin from the “objects” sheet, you’ll see that the “Is Sensor” option is checked in the Physics tab:

That is because you want the player to trigger a collision response when he touches a coin, so that you can assign points to the user, but you don’t want the mouse to behave like it’s colliding with the coin.

What about the laser? If you look at the laser property (in the Animations.pshs scene), that sprite does not have the “Is Sensor” option selected:

Why? Don’t we want the same behavior? You do, but your need to keep track of the lasers’ animation requires that you handle them differently.

If a sprite has “Is Sensor” selected, the collision will be triggered only when the player (the mouse) first touches the sprite. But for your lasers, you need the possibility of continuous collisions (every frame), because from one frame to another, the animation of the laser might change (from off to on, for example) while the player is still in contact with the laser.

If you have “Is Sensor” enabled for the lasers, and the player makes contact with a laser when the laser is off, you get a collision detection – but you wouldn’t fry the mouse, because after all, the laser is off.

But say that the laser then turns on. However, because the collision was already detected, you have no way of knowing if the player is still touching the laser or not.

How can you solve this? It’s easy. Using LevelHelper’s collisions behavior together with Box2D, you can disable the collision response so that the mouse will move across the laser without behaving like it’s colliding with the laser. This way, you can have collision triggers for every frame, and you’ll know if you need to kill the player.

Implementing Collisions: Coins

OK, finally time to code! Open your Xcode project, navigate to HelloWorldLayer.mm and add this new method to it:

-(void)setupCollisionHandling {
    [loader useLevelHelperCollisionHandling];
    [loader registerBeginOrEndCollisionCallbackBetweenTagA:PLAYER
                                                   andTagB:COIN
                                                idListener:self
                                               selListener:@selector(mouseCoinCollision:)];
}

Next, call this new method at the end of init (right before the call to scheduleUpdate):

[self setupCollisionHandling];

So what does the code do here?

setupCollisionHandling first tells the LevelHelperLoader instance that it wants to use LevelHelper collision handling and not create its own collision handler. My advice is: always use this option – its fast, easy and painless.

Next, register the method that LevelHelper should call whenever a collision between a sprite with the tag PLAYER (in this case the mouse sprite) and a sprite with the tag COIN (which is any coin sprite here) happens.

Remember how we set up collision tags for these in part two? LevelHelper automatically generates constants for these tags so that you can use them in code! You can control-click on one of the tags and choose “Go to definition” if you’re curious about where they are defined.

LevelHelper collision handling has multiple types of collision notifications but here you use beginOrEnd because your coin sprites are defined as sensors and Box2D handles collision notifications for sensor objects only at the “begin” state.

Now let’s add the method that will be used for collisions between the player/mouse and coin:

-(void)mouseCoinCollision:(LHContactInfo*)contact {        
    LHSprite* coin = [contact spriteB];
    if(nil != coin) {
        if([coin visible]) {
            [self scoreHitAtPosition:[coin position] withPoints:100];
        }
        [coin setVisible:NO];
    }
}

As you’ll notice, this method gets a pointer to an LHContactInfo object as a parameter. This is a special class that provides info about the collision. Go to its definition to see what other information you receive via this object.

So how do you get the coin sprite from this collision? Well, you registered the coin sprite as being tagB in a call to registerBeginOrEndCollisionCallbackBetweenTagA:andTagB:. So if tag B is the coin, then we access the sprite using [contact spriteB].

If you want to learn more about the LHContactInfo class, check out the Documentation tab in LevelHelper.

Next, you make sure that the coin is not nil. This is not strictly necessary, but it’s a good way to avoid errors. As a general note, it’s always good to check against nil.

If the coin is visible, you call a method (that you’ll add next) to give points to the user for grabbing the coin. You then set the coin to be invisible so as to provide visual feedback to the user that s/he now has the coin in their virtual wallet.

Next, add scoreHitAtPosition:withPoints: as follows:

-(void)scoreHitAtPosition:(CGPoint)position withPoints:(int)points {    
    score += points;
}

This means that you need to add a new score variable in HelloWorldLayer.h:

int score;

Compile and run. You’ll see that when the mouse collides with the coins, the coins disappear!

Collecting coins in our game