Create a Collect-the-Pieces Game with Corona

In this tutorial, I will show you how to create a collect-the-pieces game using the Corona SDK and the Lua programming language. We will explore how to use touch controls and events, create shapes using the graphics API, and we will also make use of physics collisions and timers. Let's get started.

1. Application Overview

In this game, the player will be able to control a puck on the screen to collect other pieces with the same color. The player has only a limited time to collect as many pieces as possible. If the player touches a piece from another color, the game is over.

This application uses the Graphics 2.0 Library. If you're using an older version of the Corona SDK, you may run into problems. Consult the migration guide for more information.

In this project you will learn the following skills:

physics collisions

create text fields

user timers and images

how to use touch controls and events

create shapes using the new Graphics API

2. Target Device

The first thing we have to do is select the platform we want to run our application on. This enables us to choose the correct sizes for the artwork that we'll use.

The iOS platform has the following requirements:

iPad 1/2/Mini: 1024px x 768px, 132 PPI

iPad Retina: 2048px x 1536px, 264 PPI

iPhone/iPod Touch: 320px x 480px, 163 PPI

iPhone/iPod Retina: 960px x 640px, 326 PPI

iPhone 5/iPod Touch: 1136px x 640px, 326 PPI

Since Android is a more open platform, there are many devices and possible resolutions. A few of the more common ones are listed below:

Asus Nexus 7 Tablet: 800px x 1280px, 216 PPI

Motorola Droid X: 854px x 480px, 228 PPI

Samsung Galaxy SIII: 720px x 1280px, 306 PPI

In this tutorial, we'll be focusing on the iOS platform and the iPhone and iPod Touch in particular. However, the code used in this tutorial can also be used for the Android platform.

3. Interface

We'll use a simple and friendly interface with multiple shapes, buttons, bitmaps and more. The artwork for the interface can be found in the source files of this tutorial.

4. Export Graphics

Depending on the device you've selected, you may need to convert the graphics to the recommended resolution (PPI), which you can do in your favorite image editor. I used the Adjust Size… option in the Tools menu of the Preview application on OS X. Remember to give the images a descriptive name and save them in your project folder.

5. Application Configuration

We'll use a configuration file, config.lua, to make the application go full screen across devices. The configuration file shows the original screen size and the method used to scale the content in case the application is run on a different resolution.

6. main.lua

Let's write the actual application. Open your preferred Lua editor. Any plain text editor will work, but it is recommended to use a text editor that has syntax highlighting. Create a new file and save it as main.lua in your project folder.

7. Code Structure

We'll structure our code as if it were a class. If you're familiar with ActionScript or Java, you should find the project structure familiar.

8. Hide Status Bar

This code snippet hides the status bar. The status bar is the bar at the top of the device's screen that shows the time, signal, and other indicators.

9. Default Anchors

Setting the display's default anchors is useful if you're porting an application from the previous Graphics library, that is, the projects you've created with previous version of the Corona SDK. Since the release of the Graphics 2.0 library, the reference point of every image has changed from its top-left to its center. To change this in every image that you use in your project, we can invoke the setDefault method and pass a value from 0.0 to 1.0, with 0.0 being the left if you change the x anchor and the top if you change the y anchor.

display.setDefault('anchorX', 0)
display.setDefault('anchorY', 0)

10. Import Physics

We'll be using the physics library to handle collisions. Import and start the library using the code snippet shown below.

-- Physics
local physics = require('physics')
physics.start()

11. Background

A simple background for the application's user interface. The code snippet below draws the background to the screen.

18. Variables

The next code snippet lists the variables that we'll use in the game. The totalPucks variable stores the number of pucks that are placed on the stage, timerSrc keeps a reference to the game's timer, and time references the rectangle that shows the remaining time.

-- Variables
local totalPucks = 20
local timerSrc
local time

19. Declare Functions

We declare the functions as local at the very beginning. In Lua, you can forward declare a function by declaring its name before implementing the function's body. This makes it easier to keep track of the various functions that we'll use in this project.

20. Constructor

Let's start by creating a stub implementation for the function that will initialize the game logic, the Main function.

function Main()
end

21. Add Title View

Next, we draw the title view to the screen and add a tap listener to each button. The newImage method is used to load the images and display them on the screen using the positions passed to the function. We also create a group named titleView that serves as a container for the newly created elements.

22. Start Button Listeners

In startButtonListeners, we add the event listeners to the title view's buttons. When the play button is tapped, we show and start the game. When the credits button is tapped, we show the game's credits.

25. Show Game View

When the player taps the play button to start a new game, the title view is tweened from the stage and hidden. This shows the game view. The game view is the heart of the game. Let's break the rest of the showGameView step by step.

On iOS, you have access to a wide range of fonts. On Android there are only three fonts available; Droid Sans, Droid Serif, and Droid Sans Mono.

27. Timer

In the next step, we create the timer's rectangle shape using Corona built-in vector graphics library. The newRect function creates a rectangle that is 20pt wide, 6pt tall, and it places it in the top-right of the stage. The default color of new shapes is white so we need to change the rectangle's color by invoking setFillColor and passing in an RGB value. The Graphics 2.0 library doesn't use values ranging from 0 to 255 for RGB values. Instead an RGB value is expected to range from 0.0 to 1.0.

31. Create Pucks

In createPucks, we use a for loop to instantiate the pucks. The number of pucks is stored in totalPucks, which we set to 20 a bit earlier in this tutorial.

A random position is calculated for each puck using math.random. We also use math.random to help us load a different color from the project's images. How does this work? We generate a random integer between 1 and 4, and add the result to the name of the image that we want to load. For example, if the random number is equal to 3, the game loads an image named puck3.png.

32. Move Function

We use touch events to let the player move the pucks. When the player touches a puck, it is aligned with the position of the touch, the player's finger, and is then moved by updating its position. We also add a collision listener to the active puck to detect when the puck collides with another puck. This event listener is removed when the player releases the puck by lifting their finger from the screen.

33. Timer

The reduceTimer function is in charge of the timer rectangle we created earlier. Every second, the width of the shape is reduced by setting its xScale property and it is removed from the stage when it's no longer visible. An alert view is shown to the player when the time's up.

We first check whether the names of the pucks are the same to see if their color matches.

If they have the same color, we play a sound effect.

The player's score is increased by 50 points and the score text field is updated.

If the color of the pucks don't match, a different sound effect is played and the game over alert view is shown to the player.

35. Alert

The alert function is a simple helper function to show an alert view and animate it. We stop the audio after 700 milliseconds to make sure that we can play a sound effect. The game listeners are removed to end the game and we show an appropriate image to the player.

36. Call Main

To start the game, we invoke the Main function as shown below.

Main()

37. Loading Screen

On the iOS platform, the file named Default.png is displayed while the application is launching. Add this image to your project's source folder, and it will be automatically added by the Corona compiler.

38. Icon

Using the graphics you created earlier, you can now create a nice icon. The dimensions of the icon size for a non-retina iPhone are 57px x 57px, while the retina version needs to be 114px x 114px. The artwork for iTunes is required to be 1024px x 1024px. I suggest creating the iTunes artwork first and then creating the smaller sized images by scaling the iTunes artwork down to the correct dimensions. There is no need to make the application icon glossy or add rounded corners as this is taken care of by the operating system.

39. Testing in the Simulator

It's time to test our application in the simulator. Open the Corona Simulator, browse to your project folder, and click Open. If everything works as expected, you're ready for the final step.

40. Build

In the Corona Simulator, go to File > Build and select the target device. Fill out the required fields and click Build. Wait a few seconds and your application is ready to test on a device and/or to be submitted for distribution.

Conclusion

In this tutorial we've learned about touch listeners, collision detection, and physics, as well as a few other skills that can be useful in a wide number of games. Experiment with the final result and try to modify the game to create your own version. I hope you liked this tutorial and found it helpful. Thank you for reading.