Creating a Puzzle App

Daniel Williams

September 2013

(For more resources related to this topic, see here.)

A quick introduction to puzzle games

Puzzle games are a genre of video games that have been around for decades. These types of games challenge players to use logic and critical thinking to complete patterns. There is a large variety of puzzle games available, and in this article, we'll start by learning how to create a 3-by-3 jigsaw puzzle titled My Jigsaw Puzzle.

In My Jigsaw Puzzle, players will have to complete a jigsaw puzzle by using nine puzzle pieces. Each puzzle piece will have an image on it, and the player will have to match the puzzle piece to the puzzle board by dragging the pieces from right to left. When the puzzle piece matches the correct location, the game will lock in the piece. Let's take a look at the final game product.

Downloading the starter kit

Before creating our puzzle app, you can get the starter kit for the jigsaw puzzle from the code files available with this book. The starter kit includes all of the graphics that we will be using in this article.

My Jigsaw Puzzle

For the Frank's Fitness app, we used Corona's built-in new project creator to help us with setting up our project. With My Jigsaw Puzzle, we will be creating the project from scratch. Although creating a project from scratch can be more time consuming, the process will introduce you to each element that goes into Corona's new project creator. Creating the project will include creating the build.settings, config.lua, main.lua, menu.lua, and gameplay.lua files.

Before we can start creating the files for our project, we will need to create a new project folder on your computer. This folder will hold all of the files that will be used in our app.


The first file that we will create is the build.settings file. This file will handle our device orientation and specify our icons for the iPhone. Inside our build.settings file, we will create one table named settings, which will hold two more tables named orientation and iphone.

The orientation table will tell our app to start in landscape mode and to only support landscapeLeft and landscapeRight. The iphone table will specify the icons that we want to use for our app.

To create the build.settings file, create a new file named build.settings in your project's folder and input the following code:

settings = {
orientation =
default = "landscapeRight",
supported = {
"landscapeRight" },
iphone =
plist =
CFBundleIconFile = "Icon.png",
CFBundleIconFiles = {


Next, we will be creating a file named config.lua in our project's folder. The config.lua file is used to specify any runtime properties for our app. For My Jigsaw Puzzle, we will be specifying the width, height, and scale methods. We will be using the letterbox scale method, which will uniformly scale content as much as possible. When letterbox doesn't scale to the entire screen, our app will display black borders outside of the playable screen.

To create the config.lua file, create a new file named config.lua in your project's folder and input the following code:

application =
content =
width = 320,
height = 480,
scale = "letterbox"


Now that we've configured our project, we will be creating the main.lua file—the start point for every app. For now, we are going to keep the file simple. Our main. lua file will hide the status bar while the app is active and redirect the app to the next file—menu.lua.

To create main.lua, create a new file named main.lua in your project's folder and copy the following code into the file:

display.setStatusBar ( display.HiddenStatusBar )
local storyboard = require ( "storyboard" )


Our next step is to create the menu for our app. The menu will show a background, the game title, and a play button. The player can then tap on the PLAY GAME button to start playing the jigsaw puzzle.

To get started, create a new file in your project's folder called menu.lua. Once the file has been created, open menu.lua in your favorite text editor. Let's start the file by getting the widget and storyboard libraries. We'll also set up Storyboard by assigning the variable scene to storyboard.newScene().

local widget = require "widget"
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()

Next, we will set up our createScene() function. The function createScene() is called when entering a scene for the first time. Inside this function, we will create objects that will be displayed on the screen. Most of the following code should look familiar by now. Here, we are creating two image display objects and one widget. Each object will also be inserted into the variable group to let our app know that these objects belong to the scene menu.lua.

function scene:createScene( event )
local group = self.view
background = display.newImageRect(
"woodboard.png", 480, 320 )
background.x = display.contentWidth*0.5
background.y = display.contentHeight*0.5

logo = display.newImageRect( "logo.png", 400, 54 )
logo.x = display.contentWidth/2
logo.y = 65
function onPlayBtnRelease()

playBtn = widget.newButton{
width=200, height=83,
onRelease = onPlayBtnRelease
playBtn.x = display.contentWidth/2
playBtn.y = display.contentHeight/2

After the createScene() function, we will set up the enterScene() function. The enterScene() function is called after a scene has moved on to the screen. In My Jigsaw Puzzle, we will be using this function to remove the gameplay scene. We need to make sure we are removing the gameplay scene so that the jigsaw puzzle is reset and the player can play a new game.

function scene:enterScene( event )
storyboard.removeScene( "gameplay" )

After we've created our createScene() and enterScene() functions, we need to set up our event listeners for Storyboard.

scene:addEventListener( "createScene", scene )
scene:addEventListener( "enterScene", scene )

Finally, we end our menu.lua file by adding the following line:

return scene

This line of code lets our app know that we are done with this scene.

Now that we've added the last line, we have finished editing menu.lua, and we will now start setting up our jigsaw puzzle.


By now, our game has been configured and we have set up two files—main.lua and menu.lua. In our next step, we will be creating the jigsaw puzzle. The following screenshot shows the puzzle that we will be making:

Getting local libraries

To get started, create a new file called gameplay.lua and open the file in your favorite text editor. Similar to our menu.lua file, we need to start the file by getting in other libraries and setting up Storyboard.

local widget = require("widget")
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()

Creating variables

After our local libraries, we are going to create some variables to use in gameplay. lua. When you separate the variables from the rest of your code, the process of refining your app later becomes easier.

_W = display.contentWidth
_H = display.contentHeight

puzzlePiecesCompleted = 0
totalPuzzlePieces = 9
puzzlePieceWidth = 120
puzzlePieceHeight = 120
puzzlePieceStartingY = {
80,220,360,500,640,780,920,1060,1200 }
puzzlePieceSlideUp = 140
puzzleWidth, puzzleHeight = 320, 320
puzzlePieces = {}

puzzlePieceCheckpoint = {
{x=-160, y=76},
{x=-76, y=74},
{x=-143, y=157},
{x=-57, y=147},

puzzlePieceFinalPosition = {
{x=160, y=75},
{x=244, y=75},
{x=179, y=158},
{x=265, y=144},

Here's a breakdown of what we will be using each variable for in our app:

  • _W and _H: These variables capture the width and height of the screen. In our app, we have already specified the size of our app to be 480 x 320.
  • puzzlePiecesCompleted: This variable is used to track the progress of the game by tracking the number of puzzle pieces completed.
  • totalPuzzlePieces: This variable allows us to tell our app how many puzzle pieces we are using.
  • puzzlePieceWidth and puzzlePieceHeight: These variables specify the width and height of our puzzle piece images within the app.
  • puzzlePieceStartingY: This table contains the starting Y location of each puzzle piece. Since we can't have all nine puzzle pieces on screen at the same time, we are displaying the first two pieces and the other seven pieces are placed off the screen below the first two. We will be going over this in detail when we add the puzzle pieces.
  • puzzlePieceSlideUp: After a puzzle piece is added, we will slide the puzzle pieces up; this variable sets the sliding distance.
  • puzzleWidth and puzzleHeight: These variables specify the width and height of our puzzle board.
  • puzzlePieces: This creates a table to hold our puzzle pieces once they are added to the board.
  • puzzlePieceCheckpoint: This table sets up the checkpoints for each puzzle piece in x and y coordinates. When a puzzle piece is dragged to the checkpoint, it will be locked into position. When we add the checkpoint logic, we will learn more about this in greater detail.
  • puzzlePieceFinalPosition: This table sets up the final puzzle location in x and y coordinates. This table is only used once the puzzle piece passes the checkpoint.

Creating display groups

After we have added our variables, we are going to create two display groups to hold our display objects. Display groups are simply a collection of display objects that allow us to manipulate multiple display objects at once. In our app, we will be creating two display groups—playGameGroup and finishGameGroup. playGameGroup will contain objects that are used when the game is being played and the finishGameGroup will contain objects that are used when the puzzle is complete.Insert the following code after the variables:

playGameGroup = display.newGroup()
finishGameGroup = display.newGroup()

The shuffle function

Our next task is to create a shuffle function for My Jigsaw Puzzle. This function will randomize the puzzle pieces that are presented on the right side of the screen. Without the shuffle function, our puzzle pieces would be presented in a 1, 2, 3 manner, while the shuffle function makes sure that the player has a new experience every time.

Creating the shuffle function

To create the shuffle function, we will start by creating a function named shuffle. This function will accept one argument (t) and proceed to randomize the table for us. We're going to be using some advanced topics in this function, but before we start explaining it, let's add the following code to gameplay.lua under our display group:

function shuffle(t)
local n = #t
while n > 2 do
local k = math.random(n)
t[n] = t[k]
t[k] = t[n]
n = n - 1
return t

At first glance, this function may look complex; however, the code gets a lot simpler once it's explained. Here's a line-by-line breakdown of our shuffle function.

The local n = #t line introduces two new features—local and #. By using the keyword local in front of our variable name, we are saying that this variable (n) is only needed for the duration of the function or loop that we are in. By using local variables, you are getting the most out of your memory resources and practicing good programming techniques. For more information about local variables, visit In this line, we are also using the # symbol. This symbol will tell us how many pieces or elements are in a table. In our app, our table will contain nine pieces or elements.

Inside the while loop, the very first line is local k = math.random(n). This line is assigning a random number between 1 and the value of n (which is 9 in our app) to the local variable k. Then, we are randomizing the elements of the table by swapping the places of two pieces within our table. Finally, we are using n = n – 1 to work our way backwards through all of the elements in the table.


After reading this article, you will have a game that is ready to be played by you and your friends. We learned how to use Corona's feature set to create our first business app. In My Jigsaw Puzzle, we only provided one puzzle for the player, and although it's a great puzzle, I suggest adding more puzzles to make the game more appealing to more players.

Resources for Article:

Further resources on this subject:

You've been reading and excerpt of:

Corona SDK Application Design

Explore Title
comments powered by Disqus