Quantcast
Channel: Envato Tuts+ Game Development
Viewing all articles
Browse latest Browse all 728

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

$
0
0
This entry is part 8 of 8 in the series Make a Match-3 Game in Construct 2

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…


Final Game Demo

Here is a demo of the game we’ve been working towards, and which we will have built at the end of this part of the series:




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:

Match-3 Construct 2 tutorial

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.

Match-3 Construct 2 tutorial

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:

Match-3 Construct 2 tutorial

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:

Action: Function > Call function
     Name = "FindMatches"

Your Event should now look like this:

Match-3 Construct 2 tutorial

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:

Match-3 Construct 2 tutorial

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:

Global Variable: Chain
     Type = Number
     Initial Value = 0

Your variable should look like this:

Match-3 Construct 2 tutorial

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:

Action: FloatingPointsText > Set text
     Text = NumMatchesFound * 10 * Chain

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:

Action: System > Add to
     Variable = "Chain"
     Value = 1

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:

Match-3 Construct 2 tutorial

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:

Action: System > Add to
      Variable = Score
      Value = 10 * Chain

With this change, GivePoints should now look like this:

Match-3 Construct 2 tutorial

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:

Action: System > Set value
     Variable = Chain
     Value = 1

Your Event should now look like this:

Match-3 Construct 2 tutorial

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.


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.
  2. Select Add Event Sheet.
  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.

Global Variable: MovementPossible
     Type = Number
     Initial Value = 0

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

Condition: System > Compare variable
     Variable = MovementPossible
     Comparison = Equal to
     Value = 0

Your movement Event should now look like this:

Match-3 Construct 2 tutorial

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

Event:
     Condition: Block > Is overlapping another object
          Object = GameOverArea
     Condition: Invert: Block > IsDragging
     Action: System > Set value
          Variable = MovementPossible
          Value = 1
     Action: System > Wait
          Seconds = 1.5
     Action: System > Go to layout
          Layout = Layout 2

Your new Event should look like this:

Match-3 Construct 2 tutorial

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:

Event:
     Condition: RestartButton > On clicked
     Action: System > Go to layout
          Layout = Layout 1

Your Event should look like this:

Match-3 Construct 2 tutorial

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:

Action: System > Reset global variables

Your Event should now look like this:

Match-3 Construct 2 tutorial

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:

Match-3 Construct 2 tutorial

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!


Viewing all articles
Browse latest Browse all 728

Trending Articles