Match Three Part 2

Written by Hunter Jansen on March 30, 2017

Last time out, I wrote about all the logic involved with my javascript match three game proof of concept. However, that post didn’t talk about the more interesting aspect of how to draw and animate the collapsing of the board. I’ll be covering that in this post. If you haven’t read that post and are interested in that logic; check it out here - or just look for the previous entry on my blog.

Drawing the board (Or BoardDom, lol)

For drawing the board, I wanted to take as much advantage of the DOM as possible and wanted to avoid the manual positioning/tweening of moving cells down from their previous location. This seemed like a perfect candidate for flexbox. All a basic match three board is is a series of columns that need to align to the bottom and automatically align to bottom when tile layouts change. So that left with a dom structure like:

So we have a series of columns, containing a series of tiles - you’ll notice that each tile contains information about it’s place in the board and what type/colour it is. We use these columns to vertically align with flex box and flex end:

Here we basically just loop through the clusters and set all the tiles set for removal and set them as a deleted tile. We call this step ‘Show Matches’ - we also have a function in place to update the class on the individual tile’s styling dependant on the type of the tile.

Creating replacement tiles

So now we have a board with a bunch of tiles set up for removal. If we were to just remove those tiles, we would have a bunch of empty space at the top of the board. Now, we could just create new tiles directly in those now empty spots at the top, like a normal match three game, we want the new tiles to drop in from the top - similar to the gif below.

So we need to create tiles ABOVE the board out of site that drop down into our view port when the deleted tiles are removed. The way I chose to do this was basically this:

Loop through columns

Find tiles marked for removal

Prepend the new tile to the columns tiles (since our column's flex-box is aligned to the end)

At this point, we have our board full of tiles; some marked for deletion, with new tiles outside of the viewport ready to drop in to refill the board when the tiles are removed.

So now when we add a class of collapsing to a tile, the animation of the tile’s from height 30px to 0px over 1second fires. All we have to do is apply the collapsing class to all of the tiles set for removal:

$('.blank')
.addClass('collapsing')

Hooking into the end of the css keyframes

The animation above is super neat and all that, but currently, after it ends the tile goes back to it’s previous position. That’s about as useless as this box.

So now, we alter the above code a little bit to hook in to the animationend event that the browser fires when the key frame is over to remove the tiles from the board.

As a result - thanks to flexbox and the collapsing height on the removal cells - we get all the cells dropping into the place that they’re supposed to be, and new cells dropping in from the top to keep the board full. With this bit, we have all the major bits that we need in order to make our match three game!

Wrapping up

There’s obviously a lot that I didn’t talk about, like selecting tiles, and how to deal with the unknown asyncronous aspect of cascating and waiting. (Hint: promises) - so it’s a good thing that it’s all open source and available.

The end results can be found here with a demo available on my site (There’s output in the console as well).

The end results aren’t polished or entirely bug free - but that wasn’t really the point of this whole thing. This exercise was really just a proof of concept since I really wasn’t sure if it was possible to do what I wanted to or not.

TL;DR - It is possible!

Got any feedback, questions, or similar experiences?

Hit me up on twitter (link in the footer), make an issue on the repo (further up in the post), or drop me a line at hunter@hyperwidget.com