Corona – Triple Town style Matching Game matches Part 3

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

Leave a Reply

Your email address will not be published. Required fields are marked *