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?
Let’s Get Physical
Now that you have the player and bullet on screen, you’ll need to give them some physics properties. But wait a second…didn’t you already enable physics in the game in the very beginning?
That’s correct, you did. However, just because the physics routines exist, that doesn’t mean that they apply to anything on the screen – unless you write some code! :]
Paste the following into main.lua above “main();” and save:
-- When the game starts, add physics properties to player and bullet
function startGame()
physics.addBody(player, "static", {density = 1, friction = 0, bounce = 0});
physics.addBody(bullet, "dynamic", {density = 1, friction = 0, bounce = 0});
player:removeEventListener("tap", startGame);
gameListeners("add");
end
In the code above, you tell the player object and bullet object how dense they are, if they have any friction and if they’ll add any bounce to the collision. The call to “removeEventListener” on the player is there so the game doesn’t listen for a user tap once the game has already started.
Note: It’s good practice to remove event listeners when they aren’t needed to free up memory and device resources.
Note: It’s good practice to remove event listeners when they aren’t needed to free up memory and device resources.
Now that you have most of the important elements on screen, the next section will get things moving around!
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!