Sunday, 5 July 2015

Game#10 Match 3 Completed

Match 3 is completed and can be played here.

The game core hasn't changed much but I've added a swipe left/right type selection screen. There are only four different layouts which are used with increasing difficulty levels, but it would be easy enough to add more in.

As always the source is in Github. One thing about this code is there are very few globals. Only things that actually need to be globals ; other variables are stored in singleton objects like "SelectCtrl".

Selection

Event 1 avoids copyright and requests the key (one value, the highest accessible level), which is processed in 7 and 8.  Events 3-6 create the shops you can see in the picture to the right, tracking the UIDs of first and last level.

The shops are updated on a per tick basis starting at 9. 10-14 move the shop towards a given "targetX" - this allows us to move the shops by just setting this value. Events 15-17 copy the size and positions and the cross visibility of each Selector (the shop). Effectively it responds immediately to changing variables. Event 18,19 and 20 handle taps on the shops, setting the level and running the game. Event 21 detects a touch end with swipe. Event 22/23 and 24/25 are very similar - the check is for direction, the first (or last) shop not being on the screen, and it not already being in motion. If this passses it sets the targetX value to move it.

Main Game

The game is driven by a state machine.

Setup

The primary purpose of setup is given a definition string specifying a level to create the initial display. It also contains the dropping code. Event 4 gets the string and decodes it into specific values. Event 5 takes the last part (defining the screen layout) and works out the level dimensions, and from that it works out how big each cell is and where they are. Events 6 and 7 create the grid where there is an "X" (e.g. event 9) and it also adds the grey behind tile. Where there isn't an "X" it creates a launcher, an object which spawns candies. Event 10 creates a row of blockers at the bottom of the grid. (If you disable comment 13 you will see these things in position, also see 2 posts back). Event 11 and 12 handles Launchers followed by Launchers or Blockers, replacing them with Blockers.

Event 14 onwards handles the dropping when the state is DROPPING. Firstly all the launchers are chosen (16) and if they do not already contain an item one is spawned (17). Event 18 access the items in backwards order up the screen, and if they are moving works out a new position (Event 19), If there is a collision with a stopper (blocker/launcher) or another item then the collision flag is set. In event 23, if there was a collision, the item is stopped and it is locked to a cell, otherwise Y is updated with the new position, moving it down the screen.

Events 26-29 cause the pulsing effect, and 30-33 is a function counting the number of items still moving that are in the game.

Matches

Matches is almost all code rather than events. It is a function that for each square counts the number of duplicates in a horizontal and vertical direction (right and down). Most of the work is done in 4, which calls two functions to scan in the directions and maintains the "best result" in each direction.

Event 6 counts the duplicate objects in a given direction. It keeps moving right (or down) whilst there is an object there in the game and the typeID (basically, the displayed graphic) is the same.

Control

Most of the work is here. We first go into NEWBLOCK state which is the start of a possible set of drops, this just resets the bonus multiplier and goes into DROPPING

DROPPING state starts at Event 5. The dropping is actually done in Setup, so 7,8,9 are just waiting for it to finish. Events 10 and 11 decide what to do next - if there is a match-3 (or ore) we go to REMOVE, otherwise we go to WAITSWAP. The first pass flag indicates the first pass, where you don't score, this is removing lines from the randomly selected items. If you watch the game it sort of "plays itself" for a few seconds creating a item grid with no Match-3s

REMOVING starts at 12. It basically picks H or V (horizontal or vertical) depending which is the best scoring, or randomly if they are the same, and then calls "destroyChunk" to delete them, having picked one match line that fits that (17,20) randomly (18,21). Effectively if there are (say) 3 vertical Matches it will pick on only. Each of these triggers an explosion, when these explosions have all finished (22) it goes back into DROPPING state to see if there are any more to process.

Events 24-29 are its helper function - it deletes n objects from x,y in direction dx,dy using a for loop. The exact behaviour depends on "first pass" - if not setting up it fires the explosions sequentially and adds to the score.

WAITSWAP is basically handling the selection and swapping over of adjacent cells. Standard Drag and Drop was deemed inadequate, so it is handled its own way. Initially, we go to EXIT (end of level) if there are no moves left.

Event 34 handles the "touch down". The calculations in the condition centre it on the middle of the Item (the collision area of the item is smaller than the bounding rectangle) and copies relevant information into a TouchManager object. Event 36 handles the drag part.

When we release in 37 (again with the centreing) we keep the drop target details (39) and if they are adjacent and not diagonal (40) we swap them over, otherwise we return the original item to its start place. Events 41,42 and 43 all deal with these tests failing, and just return the original item to its home point. These movements are handled by an ItemMover object whose responsibility it is to move an item to a position and then destroy itself - a bit like fade does.

When all the moves have finished and we swapped (44,45) we check to see if this has resulted in a Match 3, if so we start all the items moving again and go to NewBlock. If not (47) we return them to their original position.

Event 48 and 49 is a function which creates and sets up and ItemMover, and 50-52 use lerp to move it over time, 52 destroying it when it reaches the end position

Event 55 onwards is the exit state and is mostly graphic - all items explode, all tiles fade away, Layer 3 is made visible and a touch takes you back to the select screen, hopefully with "levelComplete" set - this is set when the score exceeds the target score in Event 29 when we are removing stuff.

Finally 62 is the big red button which abandons the level. You can still complete it.

Levels

I don't do much level design here, there are 4 of them (see event 3,4,5,6,7) which are concatenated with the number of discrete items that exist (6), a required score and maximum moves (all calculated in event 2). Effectively the layouts are used over and over again with harder target scores and more, but not quite enough moves.


No comments:

Post a Comment