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

This is a post by special contributor Bogdan Vladu, an iOS application developer and aspiring game developer living in Bucharest, Romania. Welcome back to our Jetpack Joyride tutorial series! In this tutorial series, we are making a game similar to Jetpack Joyride using Corona SDK, and the LevelHelper and SpriteHelper tools. So far, we’ve got […] By .

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

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 project 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 project folder, create a new folder called Music, and drag all the sound files from the sound pack into this new folder.

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 gameLogic.lua declare a couple of global variables:

local backgroundMusic = nil;
local laserSound = nil;
local coinSound = nil;
local groundSound = nil;
local bunnyHitSound = nil;
local flySound = nil;
local hitObjectSound = nil;
local loseSound = nil;

Then inside the “enterScene” method load the sounds as follows:

backgroundMusic = audio.loadStream("Music/backgroundMusic.m4a")
laserSound = audio.loadSound("Music/laser.wav")
coinSound = audio.loadSound("Music/coin.wav")
groundSound = audio.loadSound("Music/ground.wav")
bunnyHitSound = audio.loadSound("Music/bunnyHit.wav")
flySound = audio.loadSound("Music/fly.wav")
hitObjectSound = audio.loadSound("Music/hitObject.wav")
loseSound = audio.loadSound("Music/lose.wav") backgroundMusic, { channel=1, loops=-1, fadein=5000 })

Here we also start the background music playback and we set it as looping.

Now inside mouseLaserCollision(event) method add the following line just before killPlayer()

if(laser:activeFrame() ~= 1)then laserSound ) --ADD THIS LINE

Then inside killPlayer() add the following line right at the end of the method: loseSound )

Inside “mouseCoinCollision(event)” method add the following right after scoreHitAtPosition call.

 if(coin.alpha == 1.0)then
	        scoreHitAtPosition({x = coin.x, y = coin.y}, 100); coinSound ) --ADD THIS LINE

Inside onEnterFrame method add the sound right before the “if(playerVelocity > 1.5)then” line: flySound )

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:

loader:registerPreColisionCallbackBetweenTags(LevelHelper_TAG.PLAYER, LevelHelper_TAG.DOG, mouseDogCatCollision);
loader:registerPreColisionCallbackBetweenTags(LevelHelper_TAG.PLAYER, LevelHelper_TAG.CAT, 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:

function mouseDogCatCollision(event) hitObjectSound );

	loader:cancelPreCollisionCallbackBetweenTags(LevelHelper_TAG.PLAYER, LevelHelper_TAG.DOG);
	loader:cancelPreCollisionCallbackBetweenTags(LevelHelper_TAG.PLAYER, LevelHelper_TAG.CAT);

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

Tweaking Gameplay

Our game is looking good so far, but there are still a number of problems.

In my level there are places where the player can’t get past a laser because it’s active, but he can’t go under it because there’s a cat in the way. Your level may have similar problems.

It’s time to play-test the level and make any necessary modifications to be sure it’s possible for the player to successfully finish the game.

Open up LevelHelper with our level03 level, and drag the cats, dogs and laser sprites as necessary so that the player has a way through. (But don’t make it too easy!)

Make sure to save the level!

Since we’re modifying the level anyway, let’s create a way to know when the player touches the ground. To do this we’ll define a new tag and add that tag to the bottom border of the physic boundary. Click the Define Tag button (as we did in Part Two) and add the tag “GROUND.”

Now that we have this new tag, let’s assign it to the bottom part of the Physic Boundary shape.
To do this click the Physic Boundaries button.

Save your level in LevelHelper.

We still have to define the collision callback between the player and the ground. Add the following at the end of setupCollisionHandling method:

loader:registerPreColisionCallbackBetweenTags(LevelHelper_TAG.PLAYER, LevelHelper_TAG.GROUND, mouseGroundCollision);

Define the mouseGroundCollision method somewhere above the setupCollisionHandling method, as follows:

function mouseGroundCollision(event)

    if(playerIsDead == true)then
    if(playerWasFlying == true)then
		local function onAnimationEnded( event ) 
	 		if(event.phase == "end")then
	 			player:removeEventListener("sprite", onAnimationEnded);
		player:addEventListener("sprite", onAnimationEnded)
    playerWasFlying = false;

We test if the player is dead so we can return if it is. We then test if the player was flying when they touched the ground. If they were, we play landing sound.

Then we start the mouseFall animation and add a notification on the sprite. That way when the animation ends, we get notified so that we can set another animation on the player sprite. Since we run a new animation on the mouse we need to register for that animation.
Add the following where you register the animations.

animationMgr:registerAnimationWithNameOnSpriteWithName("mouseFall", "player");

We also set the animation “mouseRun”. Why are we not registering for it? Because this animation is set by default in LevelHelper and its already registered.

Playing the game now, it looks like we have almost everything in place. But there is still one thing we need to fix!

You may have noticed that if we run the game now, coins taken from the level don’t reappear when the parallax restarts. We hid them, remember, after player collisions, so we need to add a way to make them visible again when the parallax starts over.

Inside the enterScene method declaration, add the following line, after you’ve taken reference to the parallax node: of the code
parallaxNode = loader:parallaxNodeWithUniqueName("Parallax_1")
if(nil == parallaxNode)then  print("Could not find parallax node.") end

parallaxNode:registerSpriteHasMovedToEndListener(spriteInParallaxHasReset) --ADD THIS LINE of the code

This new method registers on the parallax another new method (spriteInParallaxHasReset) that will be called whenever a sprite in the parallax is reset to the back of the parallax. This method gets called when the sprite exits the view.

Define spriteInParallaxHasReset before the enterScene declaration:

function spriteInParallaxHasReset(sprite)
    if(LevelHelper_TAG.COIN == sprite.lhTag)then
		sprite.alpha = 1;

Here we test the tag of the sprite that was reset by the parallax, and if it’s tagged as a COIN we make it visible again.

Compile and run your game, and see how long you can play without dying! :]

Rocket mouse part 3 complete!