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

This is a post by special contributor Bogdan Vladu, an iOS application developer and aspiring game developer living in Bucharest, Romania. Update 1/9/2013: This tutorial is now deprecated. We now have a newer, updated version of this tutorial, check it out! Welcome back to our Jetpack Joyride tutorial series! In this tutorial series, we are […] By .

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

Implementing Collisions: Lasers

The next step is to handle the collision between the lasers and the mouse.

Inside the setupCollisionHandling method, add the following at the end:

[lh registerPreCollisionCallbackBetweenTagA:PLAYER andTagB:LASER idListener:self selListener:@selector(mouseLaserCollision:)];

Here we’ve registered a pre collision callback between the player and the lasers. Now we need to define the mouseLaserCollision method.
We did this because the laser sprites are not sensors and we want to receive notification about this collision on every frame in order to kill the mouse when the laser has become active.

Put the following after the mouseCoinCollision:

-(void)mouseLaserCollision:(LHContactInfo*)contact
{        
    LHSprite* laser = [contact spriteB];
    
    int frame  = [laser currentFrame];
    
    // If we make the laser a sensor, the callback will be called only once - at first collision.
    // This is not good as we want to kill the player when the laser changes to active.
    // So we disable the contact so that the player and laser don't collide, but trigger a collision.
    // Disabling the contact is only active for one frame,
    // so on the next frame the contact will be active again, triggering the collision.
  
    b2Contact* box2dContact = [contact contact];    
    box2dContact->SetEnabled(false);
    
    if(playerIsDead)
        return;

    if(frame != 0)
    {
        [self killPlayer];    
    }
}

In the above code, we take the sprite B from the contact info. In our case sprite B is the laser. Then we take the current frame from the sprite, because we need to test if the laser is active and kill the player if it is.

We then take the Box2d contact information from the LevelHelper contact object and disable the contact so that no collision behavior will occur. We check if the player is dead. If so, we do nothing.

Finally, we test if the frame number is not 0. If it is 0, then the laser is not on, so we don’t need to kill the player. If it’s not 0, it means we need to kill the player. We cancel the collision callback because we don’t need it anymore, and kill the player.

Notice we’re using two things that we have not yet defined: the killPlayer method and the playerIsDead variable. So let’s define them.

Inside HelloWorldScene.h, put the following in the class declaration:

bool playerIsDead;

Then define the killPlayer method inside HelloWorldScene.mm (add after mouseCoinCollision):

-(void)killPlayer
{     
    playerVelocity = 0.0;
    playerShouldFly = false;
    playerIsDead = true;
    playerWasFlying = false;
    [rocketFlame setVisible:NO];
    [player startAnimationNamed:@"mouseDie"];

    [paralaxNode setSpeed:0];
    
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    CCLabelTTF *label = [CCLabelTTF labelWithString:@"Game Over" fontName:@"Marker Felt" fontSize:64];
    label.color = ccRED;
    label.position = ccp(winSize.width*0.5, winSize.height*0.75);
    [self addChild:label];
    
    CCMenuItem *item = [CCMenuItemFont itemFromString:@"Restart" target: self selector:@selector(restartGame)];
    CCMenu *menu = [CCMenu menuWithItems:item, nil];
    [menu alignItemsVertically];
    
    [self addChild:menu];
}

In the killPlayer method above, we set the velocity of the player to 0. If the player was flying, it will now fall to the ground.

We then set the playerIsDead variable to true so we know the player is dead in the methods where this information is a factor. We hide the rocket flame.

Finally, we start the death animation on the player sprite by using a LevelHelper method that will take as arguments the animation’s unique name and the sprite on which we want to perform the animation. We can take the animation name from the Animations section inside LevelHelper.

For more details on using animations with LevelHelper, check out the official LevelHelper documentation.

After that, we stop the parallax from moving by setting its speed to 0.

Now we need to create a Cocos2d menu so that we can restart the game if the player dies. Let’s define the restartGame method before the killPlayer method as follows:

-(void)restartGame
{
    [[CCDirector sharedDirector] replaceScene:[HelloWorldScene scene]];
}

Compile and run, and now your mouse can die if he collides with a laser!

Mouse dies upon colliding with a laser

Gratuitous Sound Effects

If you’ve read game tutorials on this blog before, you know we’d never leave you hanging without some gratuitous (and awesome) sound effects! :]

Navigate to your Xcode Resources folder in Finder. Then, open a new Finder window and navigate to where you saved the sounds pack that you downloaded at the beginning of this tutorial.

Inside the Resources folder, create a new folder called Music, and drag all the sound files from the sound pack into this new folder.

Now go back to Xcode and include the music folder inside your Resources by right-clicking (or Control-clicking) on the Resources folder and choosing “Add Files to RocketMouse.”

In the new window, navigate to your Resources folder, select the Music folder, and click the Add button.

Your new Resources folder inside Xcode should look something like this:

Now that we’ve added our sound files to our project, let’s code the sound so we can make some noise!

At the top of HelloWorldScene.mm import the audio engine:

#import "SimpleAudioEngine.h"

Then add this new method that will load our sounds (put this right above the init method):

-(void) setupAudio
{
    [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"backgroundMusic.m4a"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"coin.wav"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"fly.wav"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"ground.wav"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"hitObject.wav"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"laser.wav"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"lose.wav"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"bunnyHit.wav"];
}

Then call this method in init (right after the call to setupCollisionHandling):

[self setupAudio];

This is where we load all the sounds in the pack. We load backgroundMusic.m4a as a music asset and we preload the rest of the files as effects.

Now we have to match the effects with the methods that will generate them. In the mouseCoinCollision method add the following:

    
[[SimpleAudioEngine sharedEngine] playEffect:@"coin.wav"];

In the mouseLaserCollision method add the following inside the if(frame != 0) statement:

    
[[SimpleAudioEngine sharedEngine] playEffect:@"laser.wav"];

Let’s also add the flying sound. Inside the tick method, add the following inside the if playerShouldFly block:

    
[[SimpleAudioEngine sharedEngine] playEffect:@"fly.wav"];

Compile and run the game, and enjoy the new music and sound effects! :]

The complete project up to this point can be downloaded here.

Collisions Between Mouse, Cats and Dogs

So far our mouse can die if he hits a laser, but he’s getting off to easy when it comes to the cats and dogs! So let’s add some collision handling for them as well.

Add the following at the end of setupCollsionHandling method:

    
[lh registerPreCollisionCallbackBetweenTagA:PLAYER andTagB:DOG idListener:self selListener:@selector(mouseDogCatCollision:)];    
[lh registerPreCollisionCallbackBetweenTagA:PLAYER andTagB:CAT idListener:self selListener:@selector(mouseDogCatCollision:)];

Let’s now define the method for the callback. Because our game will perform the same action for collisions with cats and dogs, we only need one method. Add this somewhere before the setupCollisionHandling method:

    
-(void)mouseDogCatCollision:(LHContactInfo*)contact
{    
	[[SimpleAudioEngine sharedEngine] playEffect:@"hitObject.wav"];    
    [lh cancelPreCollisionCallbackBetweenTagA:PLAYER andTagB:DOG];    
    [lh cancelPreCollisionCallbackBetweenTagA:PLAYER andTagB:CAT];    
    [self killPlayer];
}

Here we play the needed sound, then we cancel the callback between the player and the cat or dog, because we no longer need them. Then we kill the player.

Compile and run the game, and now your mouse can die when he hits a cat or dog too – so watch out! :]

Mouse dies from hitting a dog