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 5 of 7 of this article. Click here to view the first page.

I Like to Move It, Move It

The user will control the paddle by dragging it around with touch events, so you’ll need to connect some kind of touch event handler.

Paste the following code above “main();” in main.lua and save:

-- Player movement on user's drag
function movePlayer(event)
	if event.phase == "began" then
		moveX = event.x - player.x;
	elseif event.phase == "moved" then
		player.x = event.x - moveX;
	end

	if((player.x - player.width * 0.5) < 0) then
		player.x = player.width * 0.5;
	elseif((player.x + player.width * 0.5) > display.contentWidth) then
		player.x = display.contentWidth - player.width * 0.5;
	end
end

In the code above, the paddle should only move from side to side (in the X direction), so you’ll only set the player.x variable and leave player.y alone. The paddle should also stay within the boundaries of the screen, so there are checks against going too far to the left and to the right.

Now you need to find the appropriate place to call movePlayer. That sounds like another event listener! You need to call movePlayer when the user touches and drags the paddle around, so it would make sense to call it from the gameListener function you added above to control the movement of the bullet.

Remember those bookmarks you added previously? Here’s where you’ll use them!

Paste the following line above Bookmark A in the gameListeners function:

		player:addEventListener("touch", movePlayer);

And then paste this line above Bookmark B in the gameListeners function:

		player:removeEventListener("touch", movePlayer);

Now, relaunch the app in the simulator! Start the game, and you should be able to drag the paddle around. You might notice that the bullet doesn’t bounce off the paddle yet — you won’t kill too many zombies that way! :]

Time to add some collision physics to your paddle!

Rubber Bullets

Paste the following function under the movePlayer function in main.lua and save:

-- Determines bullet movement by where it hits the player
function bounce()
	velocityY = -3
	if((bullet.x + bullet.width * 0.5) < player.x) then
		velocityX = -velocityX;
	elseif((bullet.x + bullet.width * 0.5) >= player.x) then
		velocityX = velocityX;
	end
end

This is another instance where the velocityX and velocityY variables come into play. The bullet needs to change its Y direction to move up towards the zombies. However, the X direction (side to side) will depend on whether the bullet hits the left or right side of the paddle.

Time to add our event listener! :] Paste this line above Bookmark A in the gameListeners function:

		player:addEventListener("collision", bounce);

And paste this line above Bookmark B in the gameListeners function:

		player:removeEventListener("collision", bounce);

Relaunch the app in the simulator and start the game! :]

You should now be able to drag the paddle back and forth across the screen, and the bullet should bounce off. Those pesky zombies are still invincible though!

Enough with the rubber bullets — time to get some real firepower behind that bullet!

Killing Zombies and Padding Stats

Remember how you used the velocityX and velocityY variables for the bullet and paddle collisions? You’ll need to do that for the zombies as well!

Add the following code to main.lua before “main();”.

-- Zombies are exterminated, remove them from screen
function zombieDestroyed(event)
	
	-- Where did the bullet hit the zombie?
	if event.other.name == "zombie" and bullet.x + bullet.width * 0.5 < event.other.x + event.other.width * 0.5 then
		velocityX = -velocityX;
	elseif event.other.name == "zombie" and bullet.x + bullet.width * 0.5 >= event.other.x + event.other.width * 0.5 then
		velocityX = velocityX;
	end
	
	-- Ricochet the bullet off the zombie and remove him from the screen
	if event.other.name == "zombie" then
		-- Bounce the bullet
		velocityY = velocityY * -1;
		-- Zombie says "ow" when hit by a bullet
		audio.play(zombieKill);
		-- Remove zombie instance
		event.other:removeSelf();
		event.other = nil;
		-- One less zombie
		zombies.numChildren = zombies.numChildren - 1;
		
		-- Score
		score = score + 1;
		zombieKillNum.text = score;
		zombieKillNum:setReferencePoint(display.CenterLeftReferencePoint);
		zombieKillNum.x = 150;
	end
	
	-- Check if all zombies are destroyed
	if zombies.numChildren < 0 then
		textBoxScreen("City: Zombie Free", "Next City");
		gameEvent = "win";
	end
end

In the code above, when a Zombie-bullet collision occurs, the bullet needs to bounce off properly by modifying the velocityY variable.

If zombies could talk while being shot, they'd probably say "Ow!", so add that sound effect in with the collision.

The zombie should then disappear forever by removing itself from the collection of zombies, never to be heard from again.

As well, when the bullet hits a zombie, add 1 to the zombies killed score; if all the zombies are gone, show text saying the city is now zombie free!

You're almost done — you just need to add this function to the listener events! Paste this line above Bookmark A in the gameListeners function:

		bullet:addEventListener("collision", zombieDestroyed);

And paste this line above Bookmark B in the gameListeners function:

		bullet:removeEventListener("collision", zombieDestroyed);

That's it! Just for completeness, here's what the final gameListeners function should look like:

-- Listen for bullet and player collisions and user dragging player
function gameListeners(event)
	if event == "add" then
		Runtime:addEventListener("enterFrame", updatebullet);
		player:addEventListener("touch", movePlayer);
		player:addEventListener("collision", bounce);
		bullet:addEventListener("collision", zombieDestroyed);
	-- Remove listeners when not needed to free up memory
	elseif event == "remove" then
		Runtime:removeEventListener("enterFrame", updatebullet);
		player:removeEventListener("touch", movePlayer);
		player:removeEventListener("collision", bounce);
		bullet:removeEventListener("collision", zombieDestroyed);
	end
end

Note:The order of the four event listeners doesn't matter, so don't worry if you pasted them in a different order.

Note:The order of the four event listeners doesn't matter, so don't worry if you pasted them in a different order.

Relaunch the game in the simluator and give it a try!

Now when you click on the player paddle, the bullet shoots outwards and upwards, you can drag the paddle back and forth, the bullet bounces off the walls, it kills the zombies and you get a high score! All of your hard work has paid off!

Uh...wait a second. When you win nothing happens — and when you lose nothing happens! Somewhat less than gratifying, isn't it? :]

Why did this happen? You're calling the textBoxScreen function to display a message when you win or lose, so where is it?

Right — you never actually created that function yet, you just referred to it in the code! Tapping on the resulting text box should also take you to the next level. You'll fix that in the next section!