1. Code
  2. Corona SDK

Create a Space Defender Game – Game Logic

Scroll to top
Read Time: 12 mins

In this tutorial series, we will be learning how to create a space shooter game just like the classic game Space Defender. Read on!

Series Overview

In this version of Space Defender, the player will have to defend his space by shooting enemies. Every time the player successfully destroys an enemy, they will earn points and when the player has reached 20 or 40 points, their gun will receive an upgrade. To mix things up, this game will send out bonus packages that are worth 5 points. To see the game in action, watch the short video above.

Where We Left Off…

In part 1 of this series, we learned how to set up our app, how to use custom fonts, how to use a storyboard, and how to set up our main menu. In Part 2 of this series, we will learn how to create the gameplay of our app. So, let’s get started!

Our first step is to create a new file called game.lua. Once it’s created, open the file in your favorite editor.

1. Adding Libraries

Since we are starting a new scene, we have to require some libraries. We will be using the physics engine built into Corona SDK for collision detection.

2. Configuring Physics

After we have our libraries setup, we will configure the physics engine. The settings below will set the gravity to 0 (just like in space) and set the iterations to 16. The setPositionIterations means the engine will go through 16 positions per frame. Anything higher than 16 can adversely affect game performance.

3. Using A Random Generator

Although this step is not necessary for this tutorial, it's a good practice to "seed" the random number generator. I like to use the current time to seed the generator.

4. Setting Up Game Variables

Now we will define some variables for our game. Each variable has a comment next to it explaining the purpose of the variable.

5. Create the Main Game Scene

After creating the variables, we are going setup the scene inside the function scene:createScene. If you remember from Part 1, this function is used to create visual elements and game logic. In a later function, we will call upon these functions to run the game.

In the following code, we are creating the scene:createScene function and adding the background and top/bottom walls. Both walls are set up as static physics objects to prevent the player from going off screen.

6. Adding HUD Elements

Inside of the same scene:createScene function, but after the bottomwall display object, we are going to add four more display objects. Here’s an explanation of the purpose of each object.

  • btn_up, btn_down: These display objects will act as buttons on the left hand side of the screen and each object will move the ship up or down respectively. However, they are not operable until we set up the move function.
  • enemyHitBar: This display object is set up as a sensor and will only react to physic collisions. When it does react to collisions, it will remove the enemy object and subtract one from player lives.

Right after the enemyHitBar display object, we are going to add some GUI elements to display the player score and player lives. We will also show text on the screen that says "Move Up" and "Move Down" to notify the player where they need to touch to move the ship up or down.

7. Adding the Player Ship

Next, we will be adding the player’s ship to the screen. The ship will be added as a dynamic physics object so it can react to collisions with other physics objects. We will go into further depth on collisions later in this tutorial.

8. Moving the Player Ship

Do you remember the btn_up and btn_down display objects we added? We are now going to add event listeners to these objects to help make the player ship move. When btn_up is touched, we will make our speed variable negative and when btn_down is touched we will make our speed positive. By making this variable positive and negative, we are telling our next function to move the ship up or down.

9. Enabling Movement

After we've added event listeners to our btn_up and btn_down display objects, we are going to create two runtime event listeners with their respective functions. These functions will run every frame and the one catch with runtime functions is that you must specify when to stop them. We’ll cover that later. For now, the stop function will set the variable motionx to 0 (because neither button is touched) and the moveguy function will add the variable motionx to our ship’s y position.

10. Firing Bullets

By now, we have our ship moving, but it’s not firing! To get the ship ready to fire bullets, we have to create the fireShip() function. This function will create new display objects that react to physics collisions and this function will also move the object across the screen from left to right.

To make the game more interesting, we will allow the player to shoot more bullets when they reach a certain score. When the player reaches 20, the ship will shoot two bullets and when the player reaches 40, the ship will fire a third bullet that shoots downward diagonally.

11. Creating Enemies

After we’ve set up our ship to fire, we need to give the player some enemies to shoot at! We’ll create two different functions – createSlowEnemy() and createFastEnemy(). Both functions will create a physics display object that moves from right to left with the speed of the enemy and the image being the only difference.

12. Create Bonus Packages

Next, we’ll create bonus packages for our player to grab inside the function createBonus(). The createBonus() function will create a physics display objects that moves right to left and each bonus package the player grabs, they will earn 5 points.

13. Updating Player Lives

Our next to last function is the updateLives() function. This function will be called every time an enemy gets past the player to give the player the goal of defending his side of space. If the number of lives is above 0, then this function will subtract one life and update the on screen text. Otherwise, it will result in a game over scene.

In the game over scene, we are canceling all of our timers and remove all of our event listeners. With the Corona SDK, it’s very important to remember that you have to explicitly tell your app when to remove runtime listeners and timers (only when the timer is running). After these have been removed, we will display a game over message and allow the player to return to the menu.

14. Collision Detection

We are ready for our final function inside of our scene:createScene() function! This function will handle all of our collision detection by comparing the property myName of object1 to that held by object 2. Each object is passed as a parameter to this function under the variable name event.

To make it easier for you, I’ve broken down the five collision cases.

  • Case 1 – Object 1 is a bullet and Object 2 is an enemy
    What’s happening: Remove enemy and update score
  • Case 2 – Object 1 is an enemy and Object 2 is an bullet
    What’s happening: Remove enemy and update score
  • Case 3 – Object 1 is a ship and Object 2 is an bonus
    What’s happening: Remove bonus and update score
  • Case 4 – Object 1 is a enemy and Object 2 is an enemyHitBar
    What’s happening: Remove enemy and update lives
  • Case 5 – Object 1 is a enemyHitBar and Object 2 is an enemy
    What’s happening: Remove enemy and update lives

15. Syncing Movement Timers

Since we have everything set up for our game, we just need to make everything move! Inside of the function scene:enterScene() – remember that the enterScene function is outside of the createScene function – we will create 5 timers and one runtime listener. The timers will send out the bullets, enemies, and bonuses while the runtime listener will handle the collision detection.

16. Destroying the Scene

The final addition (I promise!) is the scene:destroyScene() function and the scene event listeners. The destroy scene function will make sure the physics are removed once the player leaves the scene. The scene event listeners will call the createScene, enterScene, and destroyScene respectively.


Congratulations! You have learned about a lot of things such as Corona’s storyboard feature, physics, collisions, and so much more! These are valuable skills that can be applied to almost any game and if you want to build this game for your device, I strongly recommend the official Corona documents on building for the device.

Thank you so much for reading! If you have any questions, please leave them in the comments below.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.