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 .
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How To Make a Breakout Game with Corona
50 mins
- Install Some Refreshing Corona
- Which Text Editor is Best?
- Pre-Zombie Starter
- Main is the Name of the Game
- Files, Files, Everywhere
- I Know the Status…Gone!
- But I Failed Physics in High School!
- Music Makes the Rhythm
- Varying Variables
- Settings…Variables…Where are the Graphics?!
- Listening for Interactions
- Oh, Give Me a Home Where the Zombies Will Roam
- Let’s Get Physical
- Working Hard or Hardly Working?
- Listen Up, Buster
- Where Are All The Zombies?!
- I Like to Move It, Move It
- Rubber Bullets
- Killing Zombies and Padding Stats
- I'm Back in the New York Groove
- No Texting in the Zombie Apocalypse
- One Function to Rule them All
- Where to Go From Here?
Working Hard or Hardly Working?
Take a moment and think about what the requirements of how the bullet will interact inside the game. The bullet needs to move around the screen, bounce off walls, and kill zombies.
Paste the following above “main();” in your main.lua file and save:
-- Bullet properties
function updatebullet()
-- Movement
bullet.x = bullet.x + velocityX;
bullet.y = bullet.y + velocityY;
-- If bullet hits the ceiling or left or right wall, bounce off of it
if bullet.x < 0 or bullet.x + bullet.width > display.contentWidth then
velocityX = -velocityX;
end
if bullet.y < 0 then
velocityY = -velocityY;
end
-- If the bullet hits the bottom wall, the player has lost the game
if bullet.y + bullet.height > player.y + player.height then
textBoxScreen("MY BRAINS!!", "Try Again") gameEvent = "lose";
end
end
The local variables velocityX and velocityY will control the direction of the bullet. velocityX starts out at 3, so the bullet will move to the right; velocityY starts at -3 so it will move up the screen. Both of these velocities together means the bullet will move diagonally up and to the right.
However, the bullet shouldn’t go flying off of the screen! :] You’ll need to constrain it to the display width and height. If the bullet hits the top, left, or right sides of the screen it should ricochet. If the bullet hits the bottom of the screen, that means the player didn’t successfully bounce the ball off the paddle — and the player loses the game.
The updateBullet function looks great — now you just need to call it somewhere. But where?
Listen Up, Buster
Since the bullet needs to move around continuously (at least until the player wins or loses), you want the updateBullet function to be called over and over.
You can do this by asking Corona to call the updateBullet every time it redraws the frame. Our Zombie game runs at 60 frames per second, so Corona would call updateBullet for us automatically 60 times per second.
Paste the following code into main.lua above “main(); and save:
-- Listen for bullet and player collisions and user dragging player
function gameListeners(event)
if event == "add" then
Runtime:addEventListener("enterFrame", updatebullet);
-- Bookmark A: You'll be adding some code here later
-- Remove listeners when not needed to free up memory
elseif event == "remove" then
Runtime:removeEventListener("enterFrame", updatebullet);
-- Bookmark B: You'll be adding some code here later too
end
end
Runtime is a special top-level object in Corona. Just as you added an event listener to buttons for when the user taps on them, you can add an event listener to the runtime when a frame is about to be drawn.
Note the two spots in the code above marked “Bookmark A” and “Bookmark B”; you’ll be adding elements to the gameListeners function as you go along, so keep an eye out.
Relaunch the app in the simulator! :]
After you tap on the “Play” button, tap on the paddle, and the bullet will go bouncing around the screen. You’ve added quite a bit of complicated physics here, without adding a lot of code!
Looks like you’re fully armed — now you just need something to shoot at! :]
Where Are All The Zombies?!
You came to Atlanta looking to participate in the zombie apocalypse — but where are the zombies? What a bust!
Time to add the zombies! First, here’s a quick checklist of how the zombies should behave — besides die when you shoot them, of course! :]
- Add zombies to level 1.
- Place them on top of the background image.
- Place them in rows and columns to make a wall of zombies.
- Enable physics on them so when they are hit, they make the bullet bounce off of them.
Paste the following into main.lua above the “main();” line and save:
function gameLevel1()
currentLevel = 1;
-- Place the zombies on the top layer
zombies:toFront();
-- Number of zombies on level 1
local numOfRows = 2;
local numOfColumns = 2;
-- Zombie position on screen
local zombiePlacement = {x = (_W) - (zombieWidth * numOfColumns ) / 2 + 20, y = 70};
-- 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
Most of the code above is just positioning the zombies on the screen. After you’ve set how many rows and columns you want, there’s a loop to make each zombie appear. You don’t want the zombies overlapping each other though, so the zombieWidth and zombieHeight variables from the beginning are used to space them out.
Reload the game in the simulator, and you should see some hordes of zombies descend on Atlanta!
Hooray, there are zombies to kill! If you’d like more or fewer zombies to appear on level one, simply change the number of rows and columns from 2 to whatever you’d like.
If you’re like most people, you won’t want to stand around in the face of a zombie apocalypse — you’ll want to move around a little! :] Move on to the next section to add some player movement!
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!