Welcome to a new series of tutorials in which I will show you how to build a Match-3 puzzle game, from scratch, in Construct 2. In this first part we are going to lay the groundwork for the game and get the basic puzzle grid on screen.
Introduction
A Match-3 game is a block-based puzzle where you move blocks around in the game area to create groups of three or more that share a common attribute (such as a color or a shape). In most match-3 games the player is also given bonuses for matching more than three blocks at once.
Most match-3 puzzle games are competitive in nature, and the player’s goal is generally just to get the highest score they can before their time runs out, or some other loss condition is met. Some examples of match-3 games include Pokemon Puzzle League, Bejeweled, and the recent hit Candy Crush Saga.
The Game We Will Be Making
I decided to base the match-3 game we will be making on Pokemon Puzzle League:
If you’ve never played it before, PPL is a fairly simple match-3 where blocks rise from the bottom of the game screen and the player has to create matches to prevent the game screen from filling up. If the blocks reach the top, the player loses and is forced to start all over again.
Here is a demo of the game we will be working towards throughout the series:
In this first article we are going to focus on laying the groundwork for our game. This article will focus specifically on setting up the project and spawning a grid of random blocks for the player.
Before We Begin
Before getting started with this tutorial you should make sure to install the newest version of Construct 2 (C2). When I built the original version of the game I was using Release 122, so as long as you have a newer version than that, you should be fine. On top of that, if you’ve never used C2 before you should check out this guide which details the basics of using C2 and how to make most object types.
You should also download the graphics package I created for this tutorial. While of course you can use whatever graphics you want, I will be giving specific positioning for many items in these tutorials, and those positions are based on the images I used. If you do use other graphics you will need to account for any size differences in those graphics when following these tutorials.
Once you have everything set up and have a good understanding of C2, read on!
Setting Up the Project
Before we actually build all of the gameplay, we need to set up the project itself. Load C2 and follow these steps:
- Start a new project.
- In the Project Properties, set the Window Size to
600x600
. - Fill in the Name and Author fields.
- Go to the Layers panel and add two new layers.
- Rename the lowest layer to
Background
, the middle layer toBlocks
, and the top layer toGame Field
. - Go into Layout 1 and insert a Tiled Background object.
- For the Tiled Background object, use BG Images/StandardBGTile.bmp from the graphics pack.
- Go to the object’s properties and rename it
GameBG
. - Set the object’s Layer to
Background
. - Set the object’s Size to be
650, 650
. - Position the object so it fills the entire visible area of the layout and looks similar to this:
- Now, create another Tiled Background object.
- Use the image Game Field Images/GameFieldBorder.bmp.
- Name the object
GameFieldBorder
. - Set the Position to
9, -12
. - Set the Size to
16, 732
. - Set the Layer to
Game Field
.
- Create a copy of the
GameFieldBorder
object.- Set the Position of the copy to
368, -12
.
- Set the Position of the copy to
- Next, create a Sprite object.
- Use the image Game Field Images/GameFieldBottom.png.
- Name it
GameFieldBottom
. - Set the Position to
197, 625
. - Set the Size to
344, 150
. - Set the Layer to
Game Field
.
- Make a copy of the
GameFieldBottom
object.- Set the Position to
196, -30
. - Set the Angle to
180
.
- Set the Position to
The final thing we need to do is make a background for the actual area the blocks will appear in.
- Create a new Sprite object.
- Go to the Color Picker and set the Red, Green, and Blue to
0
, and the Alpha to200
. - Use the Paint Bucket to fill the entire image with this color.
- Close the animation editor.
- Set the Size to
359, 570
. - Set the Position to
195,294
. - Set the Layer to
Background
- Go to the Color Picker and set the Red, Green, and Blue to
The game field is now complete, but we still have to make a Sprite which can be used for the Blocks.
- Make a new Sprite object.
- With the animation editor open, right-click in the Animation Frames window and choose “Import frames…“.
- Select every image in the Blocks folder from the graphics pack, and import them all.
- Delete Frame 0, so that the gray block image is Frame 0 and there is no blank frame.
- Check to make sure your frames are in the same order as my blocks in the image below:
Before we move forward, I’d like to explain the block images. The gray block is there to represent an “inactive” block, which will be implemented in an upcoming tutorial. The remaining images are grouped into sets of three for each block: the first frame is for when the block is not being used, the second is for when the player is manipulating the block, and the third is for when the block is matched into a group.
Finally, take the block we’ve made and place it somewhere in the layout that will prevent the player from seeing it during an actual game. Also, set the Block’s size to 40, 40
.
We have now brought in all the images we need for this article and can move on to actually making the game work.
Spawning a Random Block Grid
In the final version of the game the blocks will be moving up at all times, and new blocks will be pushing onto the screen from the bottom. For now, though, we need to get the basic mechanics working, so we are just going to spawn an 8×8 grid of blocks and leave it at that.
Go to Event Sheet 1 and add these global variables to define the initial spawning position of the Blocks:
Global Variable: SPAWNX Value = 49 Constant = True Global Variable: SPAWNY Value = 526 Constant = True
We also need to do one other thing before we make the first event: we need to create an instance variable for the Block that tells the block what color it is.
Create a new instance variable for the Block object, name it Color
and don’t change any other settings.
Now we will make our first event. The goal of this event is to create a static grid of blocks for testing purposes:
Event : Condition: System>On start of layout Condition: System>For Name: "Y" Start index = 0 End index = 7 Sun-Event: System>For Name: "X" Start index = 0 End index = 7 Action: System>Create Object Object: Block X = (SPAWNX + (loopIndex("X"))*Block.Width + 2) Y = (SPAWNY - (loopIndex("Y"))*Block.Width + 2)
Both of these formulas say basically the same thing. First, we add 2 to the block width so that each block has a 2px buffer between it and its neighbors to prevent false positives when using collision detection. Then, we multiply that number by the current index in the for loop, and add that to the starting X or Y position. Also, we are subtracting from the Y value because in C2 the 0 point on the Y axis is at the top of the game screen, so by decreasing the Y position’s value we are putting an object closer to the top of the screen.
So what does this accomplish? This means that as the X and Y loops iterate, and the values of X and Y increase, the position it puts each block in will change which will eventually result in a square grid:
If you run the game at this point, you will have a grid of blocks – but, rather than being different colors, they will all just cycle through every block image in succession.
To fix this we need to do two things.
First, we need to assign each block a color value using the instance variable we made earlier. To do this, add another Action:
Action: Block>Set value Color = floor(Random(1,7))
This will assign the block a random color value from 1 to 6. (The reason it’s not from 1 to 7 is explained in the explanation of the Random
function.)
Your function should now look like this:
We also need to add a system which changes the image of a block based on its value. To do this, start by adding a new Instance Variable to the Block object:
Instance Variable for Block Name: "IsMatched" Type: Boolean initial value = false
Now, add a new event:
Event: System>Every Tick Action: Block>Set Frame Value = (Block.Color-1)*3 + 1
This formula first subtracts 1 from the block’s color value to account for the fact that the values start at 1 rather than 0. Then, it multiplies that number by 3 to account for the fact that each block has 3 frames of animation. Finally, it adds 1 to that value since the standard image of a block is the first image in the set of images.
Let’s look at a quick example with a Block that has a color value of 4, to see what animation frame it will be using. First it subtracts 1 from the color value to get 3. Next it multiplies that number by 3 to make 9. Finally it adds 1 to that value to make 10. This means that a Block with a color value of 4 will use frame 10 as its default animation frame, and will be a purple/square Block.
If you run your game now you will see that every block is a different color, but we still haven’t implemented animations for when your mouse is hovering over the block or for when it is matched. This will be covered in the next tutorial, along with how to swap two neighboring Blocks.
Here is a small demo of what the game should look like at this point:
If you want to continue working on your own, start looking at changing the Block’s animation frame based on a “Mouse > Cursor is over object” event. You could also start looking at using the “Drag & Drop” behavior to manipulate the Block, and considering how to determine what the player is trying to do with the Block when they start dragging it or when they drop it.
Thanks for reading this part of the tutorial. Come back again soon for the next part of the series! You can keep up to date via Facebook, Twitter, Google+, RSS, or email.