Gravity and Matching

Today I spent a small amount of time with some engine tweaks and changing the debugging controls that I implemented in Rx. This allowed me to implement some actual game play mechanics, which progressed nicely.

For the engine side, what I did was go through all of the classes and explicitly indicate that every method that doesn’t return anything returns void. This has no impact on the generated code at all, although I guess it would tell the compiler if you tried to assign a value to a function.

More importantly, WebStorm makes wildly incorrect assumptions about what a method might possibly return if you don’t say it returns anything and then you use Control-O to override a method. For example, it might decide that the function returns undefined, or it might assume it returns nothing. This causes it to mark up the code with weird return types and also include a call to the super method that calls return.

In any case, I spent a bit of time chasing that down and tweaking the engine code, which seems to have resolved that issue nicely. I think this one is on me as I should have been doing that all along, but everything seemed to work fine without them so I initially didn’t give it much thought.

Next change up was modifying the debug code in Rx. Previously the bottle would generate with random contents and clicking inside the bottle would increment the type of segment. What we have now is a display of all of the different segment types on the left, marked with a cursor that you can manipulate with the keys 1 through 7, you can toggle color with the C key and change the Virus polygon with the V key. A click in the bottle inserts the selected item.

With that out of the way I now have the ability to set up board layouts so that I can implement actual game play mechanics.

To start I implemented a simple gravity. Starting from the second to last row in the bottle and moving upwards, we check each segment to see if there is blank space below it , and if so drop it down. The drop is accomplished by swapping the segment entity with the empty one below it, which is faster than copying properties over.

Drops only happen for single capsule segments (the round balls), and Left/Bottom capsule segments. Additionally, the Left capsule knows that it can only drop if there is space for its right hand side to drop as well, and both the Left and the Bottom carry the other end of their capsule with them when they drop. This is handy for setting up board segments, as inserting a Left capsule will cause it to start dropping right away, but inserting a Right or a Top won’t; the drop code ignores them because they get pulled along.

With that code working, I set about adding in the ability to find and destroy matches. To this end I added a new Segment type for when a segment is a part of a match, and rendered it as a simple double circle.

Some simple boolean guards are used to determine when we should look for a match; we only check for matches if on the last update at least one capsule segment fell down, and this time none fell down. We don’t want to find matches while the pieces are still in motion, after all. This also means that we don’t waste any time finding matches when the board is not changing.

Next, we scan in horizontal rows and then vertical columns, looking for groups of 4 or more adjacent similarly colored segments. For each one found, the segment type is swapped for the new Match segment type, which retains its color so that it can participate in combo matches (i.e. it can be in both a horizontal and vertical match at the same time).

During this process, we make sure to “break” any capsules by converting the other segment to a single capsule segment, which will be subject to gravity.

After a bit of testing, I set up a board similar to the second one in this video and gave it a kick start by inserting a single capsule segment; this triggers a fall, which triggers matching to happen once it stops.

Contrived example of gravity and matching in practice

Contrived example of gravity and matching in practice

I’m not sure what WordPress does with animated GIF images, but hopefully nothing too terrible.

With this part out of the way the game is nearly a fully functional prototype. The next step will be to insert viruses into the bottle to start the level. There’s an algorithm that does this to ensure that the board generated doesn’t contain matches right away and has a good distribution of colors, so that will (hopefully) be fun to implement.