How to Make a Simple iOS and Android Game with Corona Tutorial

This is a post by Tutorial Team Member Greg Pugh, author of the Colin Turtle children’s eBook app series. You can also find him on Google+. You have probably seen some stories on the news and on the web about kids that are developing mobile apps at an early age. Often they use the Corona […] By .

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

Two Walls and a Ceiling

Currently, when the game starts, the balloons all move up, up, up … and away, never to return! It’s going to be a bit difficult trying to pop balloons that don’t stay around for too long!

Create some boundaries to keep the balloons on the screen. Place the following code after the physics.setGravity line but before the startGame function:

--[[ Create "walls" on the left, right and ceiling to keep balloon on screen
	display.newRect(x coordinate, y coordinate, x thickness, y thickness)
	So the walls will be 1 pixel thick and as tall as the stage
	The ceiling will be 1 pixel thick and as wide as the stage 
--]]
local leftWall = display.newRect (0, 0, 1, display.contentHeight);
local rightWall = display.newRect (display.contentWidth, 0, 1, display.contentHeight);
local ceiling = display.newRect (0, 0, display.contentWidth, 1);

-- Add physics to the walls. They will not move so they will be "static"
physics.addBody (leftWall, "static",  { bounce = 0.1 } );
physics.addBody (rightWall, "static", { bounce = 0.1 } );
physics.addBody (ceiling, "static",   { bounce = 0.1 } );

As the comment code above tells you, you created 1-pixel thick walls around the screen, and applied physics shapes to the walls so the balloon objects will know to interact with them.

Now if you relaunch the game, you will see that your balloons don’t run away any more! :]

Let’s Play Ball(oon)!

Now that you’ve got everything displaying nicely on the screen, it’s time to think about the gameplay.

You want the user to pop as many balloons as they can by tapping them before the time expires. Depending on how many balloons they’re able to pop, you want different feedback to be displayed. So let’s do that now!

Place the following code before the physics.start() line in main.lua:

local gameTimer;

-- Did the player win or lose the game?
local function gameOver(condition)
	-- If the player pops all of the balloons they win
	if (condition == "winner") then
		screenText.text = "Amazing!";
	-- If the player pops 70 or more balloons they did okay
	elseif (condition == "notbad") then
		screenText.text = "Not too shabby."
	-- If the player pops less than 70 balloons they didn't do so well
	elseif (condition == "loser") then
		screenText.text = "You can do better.";
	end
end 

-- Remove balloons when touched and free up the memory they once used
local function removeBalloons(obj)
	obj:removeSelf();
	-- Subtract a balloon for each pop
	balloons = balloons - 1;
	
	-- If time isn't up then play the game
	if (timeLeft ~= false) then
		-- If all balloons were popped
		if (balloons == 0) then
			timer.cancel(gameTimer);
			gameOver("winner")
		elseif (balloons <= 30) then
			gameOver("notbad");
		elseif (balloons >=31) then
			gameOver("loser");
		end
	end
end

If you’re wondering about the local gameTimer declaration, that’s just to ensure that the gameTimer variable (which is set up at the end of the code, after startGame) is already present so that removeBalloons can see it since removeBalloons also refers to the gameTimer variable.

The gameOver function listens for a condition variable indicating how well the player did and displays some text based on the player’s performance.

The removeBalloons function deletes balloons as they are popped and adds each popped balloon to the score.

Since the above code just sets up the game logic, when you save your main.lua file you won’t see any changes in the simulator. These functions may look a little complex, but all they’re doing is checking to see if a user popped a balloon.

If the user pops every balloon before the time expires, the timer countdown is paused and gives the user the message “Amazing!”. If the user pops 70 or more balloons by the time the countdown reaches 0, they’ll receive the message “Not too shabby.”, and if they pop fewer than 70 by the end of the game, they will see “You can do better.”

An important piece of code that you should note is obj:removeSelf() which removes the popped balloons from memory. The removeSelf command removes a display object from screen and releases the memory used by it, as long as there are no other references to that object.

It’s the Final Countdown

You have functions to display a game over message, but where do you start the timer countdown which shows the user how much time is left? Add a countDown function that will start the background music when the game is ready to be played, and counts down the time once the game is loaded.

Place the following code right after removeBalloons:

local function countDown(e)
	-- When the game loads, the player is ready to play
	if (startTime == totalTime) then
		-- Loop background music
		audio.play(music, {loops =- 1});
		playerReady = true;
		screenText.text = "Hurry!"
	end
	-- Subtract a second from start time
	startTime = startTime - 1;
	timeText.text = "Time: "..startTime;
	
	-- If remaining time is 0, then timeLeft is false 
	if (startTime == 0) then
		timeLeft = false;
	end
end

It’s worth noting that none of these functions are being called yet – you’re just setting them up. So you still won’t see any changes in the simulator just yet!

Speaking of the startGame function, head back there and set up touch detection for each balloon so that the player can pop them by tapping on them.

In startGame, after the physics.addBody(myBalloon,… line, add the following:

    -- Allow the user to touch the balloons
	function myBalloon:touch(e)
		-- If time isn't up then play the game
		if (timeLeft ~= false) then
			-- If the player is ready to play, then allow the balloons to be popped
			if (playerReady == true) then
				if (e.phase == "ended") then
					-- Play pop sound
					audio.play(balloonPop);
					-- Remove the balloons from screen and memory
					removeBalloons(self);
				end
			end
		end
	end
	-- Increment the balloons variable by 1 for each balloon created
	balloons = balloons + 1;
	
	-- Add event listener to balloon
	myBalloon:addEventListener("touch", myBalloon);

Note that the above code is adding a function within an existing function, startGame. This may seem strange, but it’s perfectly legal! :]

The code above first increases the balloon count for each balloon (since startGame is called multiple times to create the 100 balloons), and it also sets up each balloon to detect touches and to call the myBalloon function when a touch is detected.

The rest is handled by the myBalloon function. It first checks to see if there’s time left on the clock. If the time has run out, then the player should not be able to pop balloons. And if the player is able to pop balloons, it simply plays a pop noise and calls removeBalloons to handle the rest.