Here’s a nice addition to the Triple Town like matching game. Add an animated transition to a match. The effect is that the tiles appear to merge into the final tile.
The effect is created by creating new tiles above the regular game tiles. These new tiles are only temporary. They are placed above the original tiles with the same colors and are animated toward the final tile. The motion uses alpha, so they fade to transparent when the transitions is complete. Each tile removes itself when the transitions are complete using the onComplete property.
The only new code added from the previous example, is a new function: animated_match(). This function makes use of the variables: matched_array, which contains all of the matched tiles, and match_color_index which contains the index of current color that was matched.
local function animated_match() local color = color_array[match_color_index] local t = {time=500, x=matched_array[1].x, y=matched_array[1].y, alpha=0, onComplete=remove_tile} for i = 1, #matched_array, 1 do local tile = Tile() tile:setFillColor( color.r, color.g, color.b ) tile.x = matched_array[i].x tile.y = matched_array[i].y transition.to( tile, t ) end end
Here’s a full list of the code for this example:
----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- -- Your code here local TILE_ROWS = 6 local TILE_COLS = 6 local TILE_SIZE = 50 local TILE_MARGIN = 1 local match_color_index = 0 local tile_array = {} local color_array = {} local matched_array = {} -- An array to hold matched tiles local game_group = display.newGroup() local function Color( red, green, blue ) return {r=red, g=green, b=blue} end table.insert( color_array, Color(255, 0, 0) ) table.insert( color_array, Color(0, 255, 0) ) table.insert( color_array, Color(0, 0, 255) ) table.insert( color_array, Color(255, 255, 0) ) table.insert( color_array, Color(255, 0, 255) ) table.insert( color_array, Color(0, 255, 255) ) local function Tile() local tile = display.newRect( 0, 0, TILE_SIZE, TILE_SIZE ) tile:setFillColor( 255, 255, 255, 100 ) return tile end local function remove_tile( tile ) print( "removing tile", tile ) display.remove( tile ) end local function animated_match() local color = color_array[match_color_index] local t = {time=500, x=matched_array[1].x, y=matched_array[1].y, alpha=0, onComplete=remove_tile} for i = 1, #matched_array, 1 do local tile = Tile() tile:setFillColor( color.r, color.g, color.b ) tile.x = matched_array[i].x tile.y = matched_array[i].y transition.to( tile, t ) end end local check_neighbors local check_tile_match local function get_tile_frame_at_col_row( col, row ) if col >= 1 and col <= TILE_COLS and row >= 1 and row <= TILE_ROWS then return tile_array[row][col] else return false end end function check_neighbors( tile ) -- Get the row and col of this tile local row = tile.row local col = tile.col -- Define the coords of Left, Top, Right, and Bottom local ltrb_array = { {row=0, col=-1}, { row=-1, col=0 }, { row=0, col=1 }, { row=1, col=0 } } -- print("Check from tile:".. tile.row .. tile.col .. " " .. tile.alien.currentFrame ) -- Loop through left, top, right and bottom for i = 1, #ltrb_array, 1 do local check_row = row + ltrb_array[i].row local check_col = col + ltrb_array[i].col -- Check that the row and col are on the board local n_tile = get_tile_frame_at_col_row( check_col, check_row ) if n_tile then -- on board if n_tile.color_index == match_color_index then -- matches -- Check that this tile doesn't exist in matched_array local index = table.indexOf( matched_array, n_tile ) if index == nil then -- tile hasn't been found yet! print( "match at:" .. n_tile.row .. n_tile.col ) table.insert( matched_array, n_tile ) -- add to array check_neighbors( n_tile ) -- recur this function with new tile end end end end end function check_tile_match( tile ) matched_array = {tile} -- Add the first tile to the array match_color_index = tile.color_index -- Get the index to match check_neighbors( tile ) -- Start looking for matching tiles -- Time to clear the tiles, if there are more than 2 matches if #matched_array > 2 then -- If more than two tiles match for i = 2, #matched_array, 1 do -- Loop through all but the first tile local tile = matched_array[i] -- Clear all these tiles tile.color_index = 0 tile.is_empty = true tile:setFillColor( 255, 255, 255, 100 ) end local tile = matched_array[1] -- Get the first tile and local color_index = match_color_index + 1 -- advance it's color local color = color_array[ color_index ] tile.color_index = color_index tile:setFillColor( color.r, color.g, color.b ) tile.is_empty = false animated_match() -- Want a delay here before performing the next round of matching -- Do it again in case the new match creates another match check_tile_match( tile ) end end ---------------------------------------------------------------------------------------- local function touch_tile( event ) local phase = event.phase if phase == "ended" then local tile = event.target if tile.is_empty then tile.is_empty = false tile.color_index = 1 local r = color_array[ tile.color_index ].r local g = color_array[ tile.color_index ].g local b = color_array[ tile.color_index ].b tile:setFillColor( r, g, b ) end -- Matching logic logic starts here. check_tile_match( tile ) end end local function make_grid() local tile_spacing = TILE_SIZE + TILE_MARGIN local offset_x = ( display.contentWidth - ( tile_spacing * TILE_COLS ) ) / 2 offset_x = TILE_SIZE / 2 - offset_x for row = 1, TILE_ROWS, 1 do local row_array = {} for col = 1, TILE_COLS, 1 do local tile = Tile() game_group:insert( tile ) tile.x = ( col * tile_spacing ) - offset_x tile.y = row * tile_spacing tile.row = row tile.col = col tile.is_empty = true -- set this tile to empty tile.color_index = 0 tile:addEventListener( "touch", touch_tile ) table.insert( row_array, tile ) end table.insert( tile_array, row_array ) end end make_grid()