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()