Quantcast
Channel: Envato Tuts+ Code - Mobile Development
Viewing all articles
Browse latest Browse all 1836

Create a Space Invaders Game in Corona: Project Setup

$
0
0
Final product image
What You'll Be Creating

In this three-part series, I will be showing you how to create a game inspired by the popular seventies game, Space Invaders. Along the way, you'll learn about Corona's scene management functionality, timers, moving a character, the built-in physics engine, and how to use modules to emulate classes in the Lua programming language.

1. New Project

Open the Corona Simulator, click New Project, and configure the project as shown below.
Select a location to save your project and click OK. This will create a folder with a number of icons and three files that are important to us, main.lua, config.lua, and build.settings.
We'll take a look at each file in the next few steps.

2. Build Settings

The build.settings file is responsible for the build time properties of the project.
Open this file, remove its contents, and populate it with the following configuration.

settings =
{
    orientation =
    {
        default ="portrait",
        supported =
        {
          "portrait"
        },
    },
}

In build.settings, we are setting the default orientation and restricting the application
to only support a portrait orientation. You can learn which other settings you can include in
build.settings by exploring the Corona documentation.

3. Application Configuration

The config.lua file handles the application's configuration. As we did with build.settings,
open this file, remove its contents, and add the following configuration.

application =
{
    content =
    {
      width = 768,
      height = 1024,
      scale = "letterbox",
      fps = 30,
    }
}

This sets the default width and height of the screen, uses letterbox to scale the images,
and sets the frame rate to 30. Visit the Corona documentation to learn more about the other properties you can set in config.lua.

4. Entry Point

The main.lua file is the file that the application loads first and uses to bootstrap the application. We will be using main.lua to set a few default settings for the application and use the Composer library to load the first screen.

If you're not familiar with Corona's Composer library, then I recommend giving the
documentation a quick read. In short, Composer is the built-in solution to scene (screen) creation and management in Corona. The library provides developers with an easy way to create and transition between individual scenes.

The newer Composer module replaces the older and now deprecated StoryBoard module. A migration guide is available to help convert your old projects over to use Composer.

5. Hide Status Bar

We don't want the status bar showing in our application. Add the following code snippet to main.lua to hide the status bar.

display.setStatusBar(display.HiddenStatusBar)

6. Set Default Anchor Points

To set the default anchor or registration points add the following code block to main.lua.

display.setDefault( "anchorX", 0.5)
display.setDefault( "anchorY", 0.5)


The anchorX and anchorY properties specify where you want the registration point of your display objects to be. Note that the value ranges from 0.0 to 1.0. For example, if you'd want the registration point to be the top left of the display object, then you'd set both properties to 0.0.

7. Seed Random Generator

Our game will be using Lua's math.random function to generate random numbers. To make sure that the numbers are truly random each time the application runs, you must provide a seed value. If you don't provide a seed value, the application will generate the same randomness every time.

A good seed value is Lua's os.time function since it will be different each time the
application is run. Add the following code snippet to main.lua.

math.randomseed( os.time() )

8. Avoiding Globals

When using Corona, and specifically the Lua programming language, one way to have access to variables application-wide is to use global variables.The way you declare a global variable is by leaving off the keyword local in front of the variable declaration.

For example, the following code block declares two variables. The first one is a local variable that would only be available in the code block it is defined in. The second one is a global variable that is available anywhere in the application.

local iamalocalvariable = "local"
iamaglobalvariable = "global"

It is generally considered bad practice to use global variables. The most prevalent reason is to avoid naming conflicts, that is, having two variables with the same name. We can solve this problem by using modules. Create a new Lua file, name it gamedata.lua, and add the following code to it.

M = {}
return M

We simply create a table and return it. To utilize this, we use Lua's require method. Add the following to main.lua.

local gameData = require( "gamedata" )

We can then add keys to gameData, which will be the faux global variables. Take a look at the following example.

gameData.invaderNum = 1 -- Used to keep track of the Level we are on
gameData.maxLevels = 3 -- Max number of Levels the game will have
gameData.rowsOfInvaders = 4 -- How many rows of Invaders to create

Whenever we want to access these variables, all we have to do is use the require function to load gamedata.lua. Every time you load a module using Lua's require function, it adds the moduleto a package.loaded table. If you load a module, the package.loaded table is checked first to see if the module is already loaded. If it is, then it uses the cached module instead of loading it again.

9. Require Composer

Before we can use the Composer module, we must first require it. Add the following to main.lua.

local composer = require( "composer" )

10. Load the Start Scene

Add the following code snippet to main.lua. This will make the application go to the scene named start, which is also a Lua file, start.lua. You don't need to append the file extension when calling the gotoScene function.

composer.gotoScene( "start" )

11. Start Scene

Create a new Lua file named start.lua in the project's main directory. This will be a composer file, which means we need to require the Composer module and create a composer scene. Add the following snippet to start.lua.

local composer = require( "composer" )
local scene = composer.newScene()
return scene

The call to newScene makes start.lua part of composer's scene hierarchy. This means that it becomes a screen within the game, which we can call composer methods on.

From here on out, the code added to start.lua should be placed above the return statement.

11. Local Variables

The following are the local variables we will need for the start scene.

local startButton -- used to start the game 
local pulsatingText = require("pulsatingtext") -- A module providing a pulsating text effect 
local starFieldGenerator = require("starfieldgenerator") -- A module that generates the starFieldGenerator 
local starGenerator -- An instance of the starFieldGenerator

It's important to understand that local variables in the main chunk only get called once,
when the scene is loaded for the first time. When navigating through the composer scenes, for example, by invoking methods like gotoScence, the local variables will already be initialized.

This is important to remember if you want the local variables to be reinitialized when
navigating back to a particular scene. The easiest way to do this is to remove the scene from the composer hierarchy by calling the removeScence method. The next time you navigate to that scene, it will be automatically reloaded. That's the approach we'll be taking in this tutorial.

ThepulsatingText and starFieldGenerator are two custom modules we will create to add class-like functionality to the project. Create two new files in your project folder named pulsatingtext.lua and starfieldgenerator.lua.

12. Storyboard Events

If you've taken the time to read the documentation on Composer, which I linked to earlier,
you will have noticed the documentation includes a template that contains every possible
composer event. The comments are very useful as they indicate which events to leverage for initializing assets, timers, etc. We are interested in the scene:create, scene:show, and scene:hide methods for this tutorial.

Step 1: scene:create

Add the following code snippet to start.lua.

function scene:create( event )
    local group = self.view
	startButton = display.newImage("new_game_btn.png",display.contentCenterX,display.contentCenterY+100)
    group:insert(startButton)
end

This method is called when the scene's view doesn't exist yet. This is where you should initialize the display objects and add them to the scene. The group variable is pointing to self.view, which is a GroupObject for the entire scene.

We create the startButton by using the Display object's newImage method, which takes as its parameters the path to the image and the x and y values for the image's position on screen.

Step 2: scene:show

Composer's scene:show method has two phases. The will phase is called when the scene is still off-screen, but is about to come on-screen. The did phase is called when the scene is on-screen. This is where you want to add code to make the scene come alive, start timers, add event listeners, play audio, etc.

In this tutorial we are only interested in the did phase. Add the following code snippet to start.lua.

function scene:show( event )
    local phase = event.phase
    local previousScene = composer.getSceneName( "previous" )
	if(previousScene~=nil) then
		composer.removeScene(previousScene)
	end
   if ( phase == "did" ) then
       startButton:addEventListener("tap",startGame)
   end
end

We declare a local variable phase, which we use to check which phase the show method is in. Since we will be coming back to this scene later in the game, we check to see if there is a previous scene and, if so, remove it. We add a tap listener to the startButton that calls the startGame function.

Step 3: scene:hide

Composer's scene:hide method also has two phases. The will phase is called when the scene is on-screen, but is about to go off-screen. Here you will want to stop any timers, remove event listeners, stop audio, etc. The did phase is called once the scene has gone off-screen.

In this tutorial, we are only interested in the will phase in which we remove the tap listener from the startButton.

function scene:hide( event )
    local phase = event.phase
	if ( phase == "will" ) then
		startButton:removeEventListener("tap",startGame)
	end
end

16. Start Game

The startGame function is called when the user taps the startButton. In this function, we invoke the gotoScene composer method, which will take us to the gamelevel scene.

function startGame()
    composer.gotoScene("gamelevel")
end

17. Game Level Scene

Create a new file named gamelevel.lua and add the following code to it. This should look familiar. We are creating a new scene and returning it.

local composer = require("composer")
local scene = composer.newScene()

return scene

18. Add Scene Listeners

We need to add scene listeners for the create, show, and hide methods. Add the following code to start.lua.

scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )

19. Test Progress

If you test the game now, you should see a black screen with a button you can tap. Tapping the button should take you to the gamelevel scene, which is now just a blank screen.

Conclusion

This brings this part of the series to a close. In the next part, we will start implementing the game's gameplay. Thanks for reading and see you in the second part of this series.

2014-12-31T15:20:08.000Z2014-12-31T15:20:08.000ZJames Tyner

Viewing all articles
Browse latest Browse all 1836

Trending Articles