Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From \$16.50/m

# Make a Match-3 Game in Construct 2: Chaining and Game Overs

Difficulty:BeginnerLength:LongLanguages:
This post is part of a series called Make a Match-3 Game in Construct 2.
Make a Match-3 Game in Construct 2: Eliminating Pre-Made Matches

The time has finally come: we are just about done with our game, and are ready to implement the final gameplay mechanic. This article will focus on making a combo system that gives the player more points for creating chains that destroy multiple groups of blocks after only one swap.

On top of that, we will implement the loss scenario and add a Game Over screen. Finally, I'll talk about things you can work on in your own time to improve on and expand the game beyond what we have covered. So, without further ado, let's get started...

## Finding Matches

Before we move on to the main article, I want to make a small change to when FindMatches gets called.

While working on this article, I discovered an issue that you can see in the GIF below:

As you can see in this first GIF, when a block is dropped only one block distance to try and form a match with a group of blocks at the bottom of the fall, it works perfectly.

In this second GIF, though, it becomes clear that when a block is dropped a greater distance in the same scenario, it fails to detect the match until we perform another swap. The reason for this is that the game is not looking for matches often enough.

Right now, the game only looks for matches after a swap, but because of the amount of time it takes a Block to fall this distance, the match detection has already ended when the Block hits the ground and so the match isn't found until it is re-initiated.

To fix this, we'll modify when we perform a FindMatches check.

First go to the SwapBlocks function and remove the final Event from the function so that it does not call FindMatches at all.

SwapBlocks should look like this now:

At this point, there is no Event calling FindMatches. We'll fix this by adding a new Action to the Event which detects when Matches are possible. Find this Event and add this Action to the end of the Else Event:

Your Event should now look like this:

Also, take this chance to move both of the MatchesPossible Events to the end of the game code, if you haven't already. Doing this will ensure that they are not called at all before the code which eliminates pre-made matches.

If you run the game now, you should be able to perform the scenario I presented above without issue.

## Chaining

With that issue fixed, we are going to implement the chaining system, which gives the player extra points for matches that are caused by the destruction of another match.

You can see an example of the type of situation I mean below:

In the above scenario, the player moves the green block and creates a match. Then, the destruction of the green blocks causes the blue blocks to fall and create another match moments later.

I want to give the player bonus points for achieving something like this. Specifically, I want to apply a multiplier to the number of points the player receives for each match, and have the multiplier increase with each consecutive match that is made.

### Making It Work

To make this system work, we are going to make a new variable called Chain, and then make a few small modifications to a the existing functions. So, first create a new Global Variable:

Your variable should look like this:

This variable will act as a multiplier for the points to tell it how long a chain has been going.

Now go to the Event which causes the blocks to fall, and remove the Else Event that calls the FindMatches function.

Now go to FindMatches itself and find the locations where you make the FloatingPointsText objects. Modify the Set Text statements so that they use a new formula:

This change makes the floating text be modified in the same way that the Points themselves eventually will.

Next, go to the section of FindMatches where you call FindMatches again at the end of the Event, and delete this function call and the Wait statement. Why? Because, if we did not remove these, then FindMatches would end up getting called too many times and the chains would never be initiated correctly.

(Because of the changes we made earlier in this article, FindMatches will be called whenever all Blocks are in the grid and none are falling. Having multiple areas where we call FindMatches would just cause multiple instances of the function to be running at the same time, and could mess up the points system.)

Finally, we will make one other change to this function. Go to the end of the function and add this Action after you set PointsGiven to 0:

Now, whenever the game finds matches, it gives the player points, destroys the blocks, and then increases the Chain value.

The new version of FindMatches should look like this:

Next, go to the GivePoints function and modify both Actions that increase the value of the Score so that they take the Chain value into account:

With this change, GivePoints should now look like this:

### Resetting the Chain

We have implemented the variable Chain as a multiplier for the points the player is receiving (and the number of points that are displayed in the floating text objects), but there is still one thing we need to do: we need to add in a statement that resets the value of Chain so that it will not just increase infinitely.

We are going to add this statement to the On DragDrop Start Event so that, whenever the player starts dragging a new Block, it is regarded as a new Chain. The other reason we are doing it here is because it prevents the Chain value from being reset prematurely, thus making all of the matches in the latter part of a Chain less valuable.

Go to the On DragDrop Start Event and add this Action to the Actions list:

Your Event should now look like this:

If you test the game at this point you should see that if you make a chain like the one I demonstrated in the gif earlier, you receive 90 points instead of 60 points.

With that working, the chaining system is complete and you should be able to create as elaborate a chain as you want without issue.

## Fixing Falling

The next thing I want to cover is an issue I've found with the Block falling system. If you spend any major amount of time playing our Match-3 game in its current state, you may have noticed an issue where, every now and then, a Block will fail to fall even though there is no Block under it.

You can see what I mean in the image below:

Despite there being no Block below the yellow Block, it has still failed to fall into the empty space. This is a rare issue, but if it's not dealt with it could still mess up someone's score and prevent them from receiving a chain they set up, or even cause them to lose once we add the Game Over feature.

The issue comes from the variable BlockBeingMoved, which is used by the Event that determines when Blocks should fall to ensure that there are no Blocks being moved when it tells a Block to fill in an empty space. In some scenarios, when the player moves a Block, this variable never resets, and the Blocks don't fall until another Block is moved and it resets correctly. To fix this, we are going to add a pair of Events that will set and reset this variable correctly, and we will remove the current Actions that are setting the variable, since they are not working correctly.

First, go to the OnDragDrop Start and On DragDrop Drop Events, and remove all of the Actions that deal with the BlockBeingMoved variable from these Events. There should be one Action in each Event which needs to be deleted.

Next, go to the Event that detects when there is an empty space below a Block. We are going to modify the Conditions of this Event. First make sure that the Condition that checks whether BlockBeingMoved is equal to 0 is at the beginning. Then, add another condition to the end of the Event which checks to ensure that no Blocks are being moved.

This is the condition you'll add:

Your Event should now look like this:

Finally, we are going to add two more Events at the end of the Event Sheet which will handle the BlockBeingMoved variable. Go to the end of your Event Sheet and add these Events:

Your new Events should look like this:

These Events will effectively change BlockBeingMoved from 0 to 1 and from 1 to 0 whenever a Block is being moved, or is not being moved, respectively. If you test the game at this point, you should be able to play as many times as you want without encountering any issues with Block falling.

## Game Over

Now that our chaining system is in place, we will add the loss scenario and a Game Over screen.

The first thing we need to do is add a new Layout that will act as our Game Over Screen:

1. On the right-hand side of the screen, right-click the Layouts folder, and select Add Layout.
3. Go to the new Layout and create a new BG Tile object.
1. Choose the image GameOverBGTile.png from the BG Images folder in the graphics pack you downloaded during the first tutorial.
2. Set the Position to -6, -7.
3. Set the Size to 613, 619.
4. Create a new Sprite object.
1. Choose the image GameOverText.png from the graphics pack.
2. Set the Position to 303, 200.
5. Create a new Button object.
1. Set the Name to RestartButton.
2. Set the Position to 262, 410.
3. Set the Size to 100, 30.
4. Set the Text to Restart.

Now that you have your Game Over screen set up, go back to your original Layout, Layout 1, and add one new item to that screen:

1. On Layout 1, create a new Sprite object.
2. Use the Paint Bucket tool to paint this sprite entirely red.
3. Close the animation editor.
4. Set the Name to GameOverArea.
5. Set the Position to 196, -30.
6. Set the Size to 344, 150.
7. Set the Opacity to 0.

You should notice that this sprite is at the same position, and the same size, as the top part of the game field. We are going to use this sprite object to detect when the player has lost by detecting when a block is colliding with it. Go to Event Sheet 1 so we can start implementing this.

### Stopping the Blocks at the Top

Before we start detecting the loss scenario, we need to add a new variable that we will use to stop the blocks when they hit the GameOverArea object so that they will no longer move. This will make it clear to the player that they have lost.

Now go to the Event where you move the blocks and add this condition:

Your movement Event should now look like this:

Now that the movement uses our new variable, we will add the Event that detects the loss condition:

The Event we just made will call the Game Over function once a Block is overlapping the GameOverArea. Now we will actually make the GameOver function.

Your two new Events should look like this:

The reason that we created a separate function instead of doing these actions within the Event that actually detects the game over, is that this Event is only looking at certain Blocks because of the Events which trigger it. As you can see in the function we made, we disable the dragging features of the Block to prevent the player from continuing to make matches after the game over is detected. If we did this in the event which detects the game over, it would only disable the Blocks which caused the game over, and every other Block would still be able to be dragged.

Now, go to Event Sheet 2; we're going to add some functionality to the RestartButton object we made earlier. Add a new Event to Event Sheet 2:

Your Event should look like this:

### Resetting the Values

If you play the game now, get a game over, and then restart, you should notice that it goes back to the original Layout, but the blocks are not moving. The reason for this is that all of the variables we have been using are Global Variables, so some of them are not automatically reset when we restart the Layout.

To reset them, we need to add an Action to our On Start of Layout Event that will manually reset them for us.

Go to the On Start of Layout Event and add this Action to the initial Event before the For loops are called:

Your Event should now look like this:

If you test again, you should no longer have this issue.

## What Should You Do Next?

At this point, we have gone over every feature that I wanted to cover within the scope of these tutorials.

You'll notice that your game still isn't exactly the same as the one in the demo above, with the biggest difference being that your game doesn't have a Start screen. I chose not to go over the creation of the Start screen, since it is almost exactly the same as creating the Game Over screen - I leave this as an exercise for you.

Instead, I am going to discuss a few features you could consider adding to your game that could make it better or more interesting.

## Specialty Blocks

The first thing I want to discuss is specialty blocks - blocks that either give the player bonuses or perform some unique function.

Most Match-3 games include specialty blocks to help break up the action and make the game more exciting. As it stands, the game can theoretically go on forever, but the gameplay never changes. Introducing special block types every now and then can help make the game more interesting when it has been going for a while.

To integrate a specialty block you will need to change the way blocks are generated, so that whenever a block is created there is a random chance it will become a specialty block. There are a number of ways to do this, but generally its best to just generate a random number between 1 and 100 and only generate a specialty block when it the random value is between 95 and 100, or some other range that you decide upon.

Your goal should be to make specialty Blocks rare, but not too rare. This way, the player will get them regularly enough to make the game more fun, but not so often that it destroys the balance of the game.

### Bomb Blocks

When it comes to specialty blocks you have a lot of options; one of the most common is a bomb block.

Bomb blocks cause extra blocks to be destroyed when they are destroyed. They are different in every game : in some games, they destroy all of the Blocks that are surrounding them; in others, they destroy an entire row or column of Blocks.

In the image below, you can see two of the bomb block types from the popular game Candy Crush Saga:

Bomb blocks are generally pretty simple to integrate:

• Start with an Event that listens for the destruction of any bomb blocks.
• Whenever one is destroyed, it should pass its position into a function that will then find and destroy all of the blocks that would also be destroyed by that bomb block.
• For example, if your bomb block is supposed to destroy all the surrounding blocks, you would pass the position of the bomb block to a function that would look at each of the surrounding positions to see if there are any blocks there.
• If it finds any blocks in these positions, it then destroys them.

### Time-Slow or Time-Stop Blocks

Another specialty block type you'll find in a lot of games is one that slows down how quickly the Blocks move, or stops them entirely.

Blocks like these are very simple to make.

• Just like with bomb blocks, you'll need an event that listens for when one of these Blocks is destroyed.
• Whenever this happens, you should either change MovementsPossible to 1 so that the blocks will stop, or modify the speed so that the blocks move very slowly.
• Then, you should start a timer that lasts for a short period of time, maybe 10 - 15 seconds. Once that timer ends, you'll reset the speed of the blocks and proceed normally.

You need to remember to account for the player activating a time-stop block while another time-stop block is already active. In this scenario, you should restart the timer or add the standard length of the timer to the existing timer and continue normally.

## Other Game Modes

You could also consider adding other game modes for when the player gets bored of the Endless mode we created.

### Timed Mode

The easiest game mode to add is one where the player has a time limit, with their goal being to get as many points as they can before the time runs out.

In this scenario, you would leave all of the game code untouched except to add a second loss condition to the game, whereby the game ends when the timer runs out (as well as when the Blocks hit the top of the screen).

When the game starts, you would begin a timer for the amount of time the mode lasts, and when the timer ends you would end the game the same way you do now.

### Puzzle Mode

In this game mode you would give the player a very specific game board that you design in advance and ask them to eliminate all of the blocks in as few swaps as possible.

(You'll probably want to turn off the block movement, since if the blocks are moving there will also be new blocks added over time.)

This mode would require you to be able to set up a specific block grid, so you would need to have a system that allows you to pass in a specific block setup when the game starts rather than generating one entirely at random like we do now.

On top of this, while this game mode would be relatively easy to implement, it would require you to do a lot of manual puzzle design so that you could create a lot of unique puzzles for the player to try and solve.

Adding a game mode like this can be quite time-consuming due to all the content creation required, but there are a lot of players that would enjoy it. It can really pay off well if you put in the time.

## Conclusion

Over the course of this tutorial series, we built an entire match-3 game from start to finish. There is a lot more that you can do with this game if you take the time and have the imagination, but there are also a lot of ways you can use the ideas I presented to help you with other game projects.

Keep working on your game, and keep exploring new ideas, because you never know when something you learned here might come in handy later.

I hope that, whether you went through the whole series or just skipped around to the parts you weren't able to do on your own, you learned something from this. If you have any issues or comments, let us know in the discussions below each article - I'd love to hear from you and see what twists you'll add. In any case, thanks for reading and good luck with your games!