How To Make a Breakout Game with Corona

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+. If you like to play video games, you’ve most likely played some variant of the classic game Breakout. The goal of Breakout is to move a paddle on the […] By .

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

I'm Back in the New York Groove

Before you create the text box that will take you to New York City after you kill all of Atlanta's zombies, first create the New York City level.

Paste the following into main.lua above the "main();" line:

-- Level 2 zombies
function gameLevel2()

	currentLevel = 2;
	bg1.isVisible = false;
	
	-- This code is the same to gameLevel1(), but you can change the number of zombies on screen.
	zombies:toFront();
	local numOfRows = 2;
	local numOfColumns = 8;
	
	-- Zombie position on screen
	local zombiePlacement = {x = (_W) - (zombieWidth * numOfColumns ) / 2  + 20, y = 100};
	
	-- Create zombies based on the number of columns and rows we declared
	for row = 0, numOfRows - 1 do
		for column = 0, numOfColumns - 1 do
			local zombie = display.newImage("images/zombie.png");
			zombie.name = "zombie";
			zombie.x = zombiePlacement.x + (column * zombieWidth);
			zombie.y = zombiePlacement.y + (row * zombieHeight);
			
			-- Add physics properties to zombies
			physics.addBody(zombie, "static", {density = 1, friction = 0, bounce = 0});
			zombies.insert(zombies, zombie);
		end
	end
end

The gameLevel2() function is almost identical to gameLevel1(). The currentLevel is now 2 rather than 1, and the Atlanta city background needs to be hidden away. In true Breakout fashion, this level is slightly more difficult, with 2 rows and 8 columns' worth of zombies.

Before advancing to level 2, you'll need to clean up the screen and reset the bullet and paddle.

Paste the following into main.lua above the "main();" line and save.

function cleanupLevel()
	-- Clear old zombies 
	zombies:removeSelf();
	zombies.numChildren = 0;
	zombies = display.newGroup();

	-- Remove text Box
	textBox:removeEventListener("tap", restart);
	textBoxGroup:removeSelf();
	textBoxGroup = nil;
	
	-- Reset bullet and player position 
	bullet.x = _W;
	bullet.y = player.y - 30;
	player.x = _W;

	score = 0;
	zombieKillNum.text = "0";
end

This function cleans up everything you created so far - it removes all the zombies, removes the text box and listener, and resets the bullet position, player position, and score.

Now you'll need the code to advance the player to level 2.

In level 2, you'll display a background image of New York City, which will be centered on the screen. In the event that the player was on level 2, lost, and reset the level to try again, you'll need to remove any left over zombies from memory. Finally, place the player and bullet on the screen in their original starting point.

Does this sound really similar to the level 1 init code? It sure does! :]

Paste the following into main.lua above the "main();" line and save.

-- New York City (Level 2)
function changeLevel2()
	
	-- Display background image and move it to the back
	bg2 = display.newImage("images/nyc.png", 0, 0, true);
	bg2.x = _W;
	bg2.y = _H;
	bg2:toBack();

	-- Reset zombies 
	gameLevel2();
	
	-- Start
	player:addEventListener("tap", startGame)
end

New York City is waiting for you to solve their zombie problem; you just need a way to get there. Maybe you can fly there on a magic text box! :]

No Texting in the Zombie Apocalypse

It's now time to create the text box that gives the user feedback and lets them retry a level or move onto the next. Here's the checklist for the text box functionality:

  1. Display the text box image in the images folder.
  2. Display text that lets the player know if they won or lost.
  3. Display text that lets the player retry the level they lost, or move onto the next level if they won.
  4. Act as a button to reset or change levels.

Sounds easy enough! But it would be even easier to put all of those elements into their own group. Perhaps the textBoxGroup variable you created in the beginning would be helpful right about now! :]

Paste the following into main.lua and save:

function textBoxScreen(title, message)
	gameListeners("remove");
	
	-- Display text box with win or lose message
	textBox = display.newImage("images/textBox.png");
	textBox.x = 240;
	textBox.y = 160;
	
	-- Win or Lose Text
	conditionDisplay = display.newText(title, 0, 0, "Arial", 38);
	conditionDisplay:setTextColor(255,255,255,255);
	conditionDisplay.xScale = 0.5;
	conditionDisplay.yScale = 0.5;
	conditionDisplay:setReferencePoint(display.CenterReferencePoint);
	conditionDisplay.x = display.contentCenterX;
	conditionDisplay.y = display.contentCenterY - 15;
	
	--Try Again or Congrats Text
	messageText = display.newText(message, 0, 0, "Arial", 24);
	messageText:setTextColor(255,255,255,255);
	messageText.xScale = 0.5;
	messageText.yScale = 0.5;
	messageText:setReferencePoint(display.CenterReferencePoint);
	messageText.x = display.contentCenterX;
	messageText.y = display.contentCenterY + 15;

	-- Add all elements into a new group
	textBoxGroup = display.newGroup();
	textBoxGroup:insert(textBox);
	textBoxGroup:insert(conditionDisplay);
	textBoxGroup:insert(messageText);
	
	-- Make text box interactive
	textBox:addEventListener("tap", restart);
end

This function places a text box sprite near the center of the screen, and sets up some labels on it for the title and message (passed in). It also sets up an event listener to wait for taps (which will call the restart function when one occurs, which you haven't written yet).

Relaunch the app in your simulator, and make your way to level 2!

Now you'll see two different feedback text boxes depending on whether you lost or beat the level.
But wait — there's no way to get rid of the textbox once it's on screen! It sounds like you'll need one more function to wrap up this game.

One Function to Rule them All

The final chunk of code you'll need will determine what to do if the player has won or lost. It's checklist time:

  1. If the player wins level 1, go to level 2.
  2. If the player wins level 2, tell them they completed the game.
  3. If the player loses on level 1, reset the score and replay level 1.
  4. If the player loses on level 2, reset the score and replay level 2.
  5. If the player completes the game, congratulate them and clean up event listeners.

Judging by the checklist, it's fair to assume you'll need a few if/then statements. Paste the following into main.lua above "main();" and save:

-- See if the player won or lost the level
function restart()
	-- If the player wins level 1, then go to level 2
	if gameEvent == "win" and currentLevel == 1 then
		currentLevel = currentLevel + 1;
		cleanupLevel();
		changeLevel2();
		levelNum.text = tostring("NYC");
	
	-- If the player wins level 2, tell them they won the game
	elseif gameEvent == "win" and currentLevel == 2 then	
		textBoxScreen("  You Survived!", "  Congratulations!");
		gameEvent = "completed";
	
	-- If the player loses level 1, then make them retry level 1 and reset score to 0
	elseif gameEvent == "lose" and currentLevel == 1 then
		cleanupLevel();
		changeLevel1();
	
	-- If the player loses level 2, then make them retry level 2 and reset score to 0
	elseif gameEvent == "lose" and currentLevel == 2 then
		cleanupLevel();
		changeLevel2();
		
	-- If the game has been completed, remove the listener of the text box to free up memory
	elseif gameEvent == "completed" then
		textBox:removeEventListener("tap", restart);
	end
end

This checks to see if the player has won or lost and sets does the appropriate thing (usually changing levels, or restarting the game).

Relaunch the app and start killing those zombies!

And there you have it, a zombie breakout game in two major cities! Look at you, you're now a professional zombie hunter! :]