## Corona – Triple Town style Matching Game Logic Part 2

The goal of this post is to create some Triple town style matching logic. Triple town if you haven’t played it is a very addictive matching game. The core concept is that you place elements on the game board. Three adjacent elements combine into a new elements. Elements combine in a progression.

In the last example I posted, I had created a grid with squares that cycled through colors: red, green, blue, yellow, magenta, cyan. This will by our progression. Tapping a square will color that square red. Three red squares will combine to form a green square, three green squares will combine to form a blue square etc.

I’ll be starting with the source code from the last post.

The first step is to retool the touch_tile() function. In the last example each touch advanced a tile through all of the colors in turn. Tapping an empty tile will color it red. Tapping other tiles will not effect.

```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```

When looking for matching tiles we might find any number of tiles that match. Define an array to hold the matched tiles. As we search for matching, and adjacent tiles, add them to this new array. When the search is complete examine the array to see how many matches there are.

The color_index property assigned to each represents the color displayed by the tile. This is what we will match. If two tiles have the same color_index they should display the same color. Create a variable to hold the match index while we search for a match.

```local matched_array = {} -- An array to hold matched tiles
local match_color_index = 0 -- Match this color index```

To search for adjacent tiles we need to look at tiles that to the left, top, right and bottom of the current tile. Tiles are stored in tile_arrays. This is organized into arrays for containing tiles for each row. For example you could access the third tile in the second row with tile_array[2][3]. Think about about it this way: tile_array[row][column].

Imagine starting at tile_array[2][3]. To look at the four tiles surrounding this tile you’d need to get tiles:

• tile_array[2][2] — left
• tile_array[1][3] — top
• tile_array[2][4] — right
• tile_array[3][3] — bottom

You could think of this as:

• tile_array[2][3-1] — left
• tile_array[2-1][3] — top
• tile_array[2][3+1] — right
• tile_array[2+1][3] — bottom

Think about the surrounding adjacent tiles as coordinates specified in rows and columns:

• 0, -1 — left
• -1, 0 — top
• 0, +1 — right
• +1, 0 — bottom

After checking each of the adjacent tiles, if there is a match we can begin the search again from that tile. With each match we add that tile to the matched_array.

When checking tiles at the edge of the board some results will fall outside of the array. We’ll need to check for this.

Here’s a rough sketch of the code that will run the matching system:

```local function check_neighbors( tile )
-- add a match to matched_array
-- for each matched tile call check_neighbors( matching_tile )
end```

This is called recession. Essentially the function above calls on itself. In Lua you’ll need to use a forward declaration or the function will not be able to “see itself”, and think it has not been declared.

```local check_neighbors -- forward declaration
function check_neighbors( tile )
-- ... code ...
check_neighbors( matching_tile )
end```

We also need some code to start the matching process and look at the results of the match check. Here’s the rough code

```local check_neighbors -- Forward decalraitons
local check_tile_match

local function get_tile_frame_at_col_row( col, row )
-- that tile at col, row is inside of the array

end

function check_neighbors( tile )
-- Check adjacent tiles for a match
check_neighbors( matched_tile )
end

function check_tile_match( tile )
-- Find all matching adjacent tiles
check_neighbors( tile ) -- Call recursive function to find all tiles
-- look at the match results and set the colors of tiles accordingly
end

local function touch_tile( event )
check_tile_match( tile ) -- Call check_tile_match() with event.target
end```

Here’s a full listing of the code:

```-----------------------------------------------------------------------------------------
--
-- main.lua
--
-----------------------------------------------------------------------------------------

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

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 Tile()
local tile = display.newRect( 0, 0, TILE_SIZE, TILE_SIZE )
tile:setFillColor( 255, 255, 255, 100 )
return tile
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

table.insert( row_array, tile )
end
table.insert( tile_array, row_array )
end
end

make_grid()
```

## Corona – Triple Town style Matching Game Part 1

Someone recently pointed out the game Triple Town for IOS. This is a really great little time waster. Game play is fun and challenging. It’s more of a board game rather than a real time game. You can play online also, they have a Flash version: http://www.tripletown.com/

The game is played on a grid, and the basic mechanic is to match three adjacent items. Matching three items of one type replaces the last item placed with a new item and removes the others. Matching three items leave you with a new advanced item. For example starting with two Grass, adding a third Grass combines all grass into a Bush. Three Bushes combine into a Tree, three trees combine into a House etc. here’s a chart:

This mechanic of combining three items and trading them up is very interesting. The game has a few other elements that add more options to game play.

I haven’t yet been able to get up to the sky tower or sky castle. I can make it up past 100K in points, then the Ninja Bears, yes Ninja Bears, cause so much trouble and I get stuck. You’ll have to play the original game if you want to meet the Ninja Bears.

The idea of finding trios of matching elements on a grid made for an interesting problem to solve. It took a few tries to get right. The solution I came up with was to look at the grid square where you placed a new “piece” and examine all of the adjacent squares for a match. From here you’ll need to recursively examine all of the matching squares for another match.

Recursion is the idea of having the same block of code execute itself. In my case I had a function that looked at a grid square, then examined the adjacent grid squares for matches. In this adjacent means top, left, right, and bottom, not diagonal. In other words starting a at grid square, look for matches in the adjacent squares, then use the same function to find other matching squares in the adjacent matches.

### Try it for yourself

I started a new Corona project. I used the basic project so i started with only the main.lua, config.lua, build.settings file. To keep things simple I will stick with the built in shape objects and avoid images for now. By avoiding images and sprites I can concentrate on functionality without getting hung up with non related issues.

### Creating a grid

The first step is to create a grid. The grid will be made up of squares, equal height and width. Each grid square will be a rectangle shape. The first step is to define some variables describing the grid.

```local TILE_ROWS = 6
local TILE_COLS = 6
local TILE_SIZE = 50
local TILE_MARGIN = 1```

These variables define the number of rows and columns in the grid. Rows run horizontal while columns run vertical. The grid will be 6 by 6. Since the tiles will be square, I used single variable to set the size. The margin is the space between tiles.

Making these variables uppercase is a convention to denote that they are constants. Constants are values that do not change, they are essentially fixed while the program runs. Lua doesn’t support true constants, the uppercase is a just a reminder.

With these variables in place at the top of our script we can change the values here to modify the grid arrangement. This is much easier, and more flexible than having the dig around in code to change things.

We will want to store all a reference to each of the tiles. For this I will use an array. For this I will define an array named: tile_array. I use the extension _array as a convention. This is not required but makes a good reminder this variable contains an array. The name also implies the array contains tiles.

All of the game elements should probably be contained in a group. This will allow use to move, scale, and rotate all of the game elements together. Here again I used an extension to remind myself that this element contains a group.

```local tile_array = {}

local game_group = display.newGroup()```

### Tile factory

To keep my code in organized blocks I like to use factory functions to create elements. In this case I need tiles so I’m going to make a function that creates tiles, and initialize them, then returns a reference to the new tile.

```local function Tile()
local tile = display.newRect( 0, 0, TILE_SIZE, TILE_SIZE )
tile:setFillColor( 255, 255, 255, 100 )
return tile
end```

This simple function creates a new rectangle of TILE_SIZE width and height. Sets the color to a transparent white. Then returns the tile. Any other standard tile features would be added here.

### Make a grid of tiles

Now that I have all of the preliminary work in place I can make the grid. The function below contains two loops. The outer loop, loops once for each row. The inner loop, loops once for each column. Imagine starting in the upper left and creating TILE_COLS number of tile squares from left to right, then moving down one row and making all of the tiles left to right, continuing this process for TILE_ROWS.

```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

print( display.contentWidth, tile_spacing * TILE_COLS, offset_x )

for row = 1, TILE_ROWS, 1 do
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
end
end
end```

### Positioning the tiles

The function above include some funny math at the top and a bit math in the middle to position the tiles. At the top I declared two local variables. Tiles spacing sets the space between each tile. This is the size of the tile plus the margin between tiles. Look inside the loop and you’ll see the x and y position of the tile is set to tile_spacing times row and col.

Tiles are positioned off their center point, and the first number we are count from is 1. I used offset_x to center the tiles inside the group. First I found the left over space by subtracting the total width of tiles from the width of the screen, then dividing by two. imagine the left over space is split on each side. Last I need to offset half the width of a tile, side the tiles are positioned on their center.

Also note that all tiles are added to the game_group.

### Adding tiles to the array

The tiles need to be added to the tile_array. The array can act as a two dimensional storage space. Which may more accurately describe our tile grid. To do this we’ll use an array to store each row and store these row arrays in the tile_array.

```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

table.insert( row_array, tile )
end
table.insert( tile_array, row_array )
end
end```

In this arrangement we will be able to access any tile with a row and col value. For example, the following would access the tile in the third row second column:

`tile_array[2][3]`

Also notice that I assigned each tile a row and col property. This way each tile will know it’s position in the grid. This will be important later one. Tapping a tile we can ask that tile it’s row and column.

### Tapping the Grid

For this I’ll add a touch event to each tile. All of the touches can be handled from the same function since all tiles will know their row and col.

I’m using touch rather than tap as it provides more options.

For testing the touch function will print out the tiles row and column.

```local function touch_tile( event )
local phase = event.phase

if phase == "ended" then
local tile = event.target
print( tile.row, tile.col )
end
end```

Using “ended” here creates an interaction that occurs after your finger lefts off the screen. I feel this might out, since if you were to touch down on the wrong tile you could drag your finger to the correct tile before the event was registered.

Register the event listener in make_grid().

```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

table.insert( row_array, tile )
end
table.insert( tile_array, row_array )
end
end```

### Cycling colors

To keep things simple I’ll stick with shapes. Clicking a tile we need to change it in some way. For now I’ll just set the color. Colors are made up of red, green and blue values. It’s a good idea to keep them in a table. To this end a factory function would work well.

```-- Make a function to return a color
local function Color( red, green, blue )
return {r=red, g=green, b=blue}
end```

In OOP languages constructors begin with an uppercase letter. I’ll follow this convention here. This is a simple function that takes three values, and returns a table containing three values r, g, and b.

Now let’s make some colors. The game will need to cycle through a series of colors in order. An array is needed to keep these organized.

`local color_array = {} -- An array to store colors`

Then make some colors and add them to the array.

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

Now tap to cycle through colors. When the game begins tiles will be empty. Tiles will take on a color when they are tapped. This means that a tile will need to keep track of it’s color. A couple variables are needed. Add a pair of property variables to each tile in make_grid().

```tile.is_empty = true -- set this tile to empty
tile.color_index = 0```

Now modify touch_tile() to handle the color change.

```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
else
tile.color_index = tile.color_index + 1
end

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
end```

This post has set a basic tile board with some interactivity. The next post will apply some Triple Town style matching logic.

Below is a complete copy of the source code from this example.

## Corona – Tower Defense Game Experiments 14

Here’s a few thoughts on setting up waves of enemies. Plants vs Zombies makes waves of zombies and puts the waves to good use. Game play gets much more exciting after the message “A huge wave of Zombies is approaching.”

The game requires that you either a starting reserve of energy or you have to start with a fewer enemies. After building your defense for a while it becomes very easy to take on the enemies. This means that a larger wave of enemies is required to make the game more interesting at this point.

There are a lot approaches you could take to creating wave of enemies. I’m going to define a wave of enemies by describing the wave in terms of time between enemies, number of enemies in wave, and pool of enemies.

Time between enemies will be the amount of time between the creation of each new enemy.

Number of enemies in wave, will be the count of total enemies in this wave.

Pool of enemies will be a listing of the types of enemies in the wave. This is the most abstract idea here. I’m going to use the pool as a list of possible enemy types that might appear in the wave. During the wave each new enemy created will be a random type chosen from the pool. The pool will be an array. By adding the same type more than once the pool can weighted.

Each wave will be initiated by a timer.

Use three variables to keep track of the wave. One and array the other an integer setting the index of the current wave in the array. The last variable will keep track of a timer that tracks the wave.

```local wave_timer -- add a timer to hold the wave
local alien_wave_index = 1 -- Use this to keep track of the current wave
-- Add an array to hold a wave of enemies
local alien_wave_array = {
{ time=2300, 		-- Time between enemies
count=10, 			-- Number of enemies in wave
pool={1,1,1,2,3}, 	-- Number and type of enemies in wave
delay=3000
} ,

{ time=1500, 		-- Time between enemies
count=20, 			-- Number of enemies in wave
pool={1,2,3}, 		-- Number and type of enemies in wave
delay=2000
}
}```

The array above holds a list of tables. Each of these tables describes a wave of enemies. Notice each table has properties of time, count, pool, and delay.

• time – sets the time in ms between enemies during wave
• count – total number of enemies in wave
• pool – an array of alien types represented in wave
• delay – time to wait after wave before starting the net wave

I added the extra delay property here as thought it might be useful to control the flow of things.

Next I needed two functions to control the waves of enemies. The make_wave() function sets up timers to run the wave. Here I create two timers. One called make_alien(). This timer takes the time and count from the current wave table. The second timer is set to total length of the current wave and is used to start the next wave.

I need to include a forward declaration here for next_wav, since this function calls make_wave and make wave calls it.

```-- Need a forward declaration
local next_wave

-- Add this function to mange creating enemies that attack in waves.
local function make_wave()
local wave_table = alien_wave_array[ alien_wave_index ]
local wave_time = wave_table.time
local wave_count = wave_table.count
local delay_after_wave = wave_table.delay

alien_timer = timer.performWithDelay( wave_time, make_alien, wave_count )
local time_til_next_wave = ( wave_time * wave_count ) + delay_after_wave
wave_timer = timer.performWithDelay( time_til_next_wave, next_wave, 1 )
end

-- Called at the end of each wave
function next_wave()
alien_wave_index = alien_wave_index + 1
if alien_wave_index > #alien_wave_array then
print( "ALL WAVES COMPLETE" )
else
print( "next wave" )
make_wave()
end
end

make_wave()```

Here’s a full listing of the code in this example:
Continue reading Corona – Tower Defense Game Experiments 14

## Corona – Tower Defense Game Experiments 13

This series of posts has been going on for some time. I’m up to 13! I’m not done with the game yet, but it does have some interesting features.

In this post I’d like to add some “explosions”. What I really want is a small animated effect to show that an enemy has been hit by a bullet. For simplicity I’ll stick with the shapes and use a circle for the explosion. This could be replaced in the future.

The strategy here will be the same as was used with everything else, use factory function to create objects, and another function to remove the object when the explosion is finished.

Explosions will be animated with a transition animating the width and height. The onComplete will be used to remove the explosion when the animation finished.

```-- Use this function to remove explosions
local function remove_explosion( explosion )
display.remove( explosion )
end

-- Use this function to make explosions
local function make_explosion( x, y )
local explosion = display.newCircle( 0, 0, 1 )
explosion.x = x
explosion.y = y
explosion:setFillColor( 0, 0, 255, 66 )
explosion.strokeWidth = 3
explosion:setStrokeColor( 0, 0, 255, 128 )
alien_group:insert( explosion )
transition.to( explosion, {width=20, height=20, time=500, onComplete=remove_explosion} )
end ```

Above are the two functions. These are pretty simple. I made the explosions blue to separate them from the enemies (green), and the defenses (red).

The explosion is added to the alien_group. This keeps them inside the game_group, since alien_group is a child of game_group, and should keep new explosions on top of existing enemies.

All that’s need now is to call make_explosion( x, y ) and pass the x and y location where the explosion should occur. Bullets hit enemies in the check_bullets() function.

```local function check_bullets()
for b = 1, #bullet_array, 1 do
local bullet = bullet_array[b]
if b > #bullet_array then
return
end
for a = 1, #alien_array, 1 do
local alien = alien_array[a]
if hit_test( bullet.x, bullet.y, alien.contentBounds ) then
if alien.life > 0 then
make_explosion( alien.x, alien.y ) -- Add an explosion on a hit
alien.life = alien.life - bullet.damage
local defense_name = bullet.defense_name

if defense_name == "Stun" then
transition.cancel( alien.transition )
local t = ( alien_target_y - alien.y ) * ALIEN_SPEED

alien.transition = transition.to( alien, { y=alien_target_y,
time=t,
delay=300,
onComplete=remove_alien } )
end

else
remove_alien( alien )
end
remove_bullet( bullet )
break
end
end
end
end
```

Find the comment in the function above. Here you can see a call to make_explosion( alien.x, alien.y ). This creates a new explosion at the location of the enemy. You might have also placed the explosion at the location of the bullet instead.

Here’s full listing:
Continue reading Corona – Tower Defense Game Experiments 13

## Corona – Tower Defense Game Experiments 12

One aspect that will make the game more interesting is the addition of different types of enemies.

Let’s refer to Plants vs Zombies as our model. Here all of the enemies are zombies but there are different types with different capabilities. Besides the standard there are zombies that move faster, zombies that withstand more damage, zombies that jump over a defense, and more.

The variety of enemies adds a lot to strategies that players can employ, and creativity that developers can employ when creating levels.

Enemy features

Enemies can have as may features as you can imagine. Here’s a few ideas that fit into the game as I have been envisioning it so far.

• speed – Some enemies move faster than others
• Toughness – some enemies take more damage to destroy than others
• Special – some enemies may have special features or attacks

To keep track of the enemy types I created an array similar to the array used for organizing defense types. Each enemy type will be described in a table with properties:

• name – name of feature
• speed – sets speed in px per second
• life – sets the starting life value for this enemy type
• green – color of enemy type

The last property, green, is just used for this example. Later we will have graphics to replace the shapes.

All of the enemy type tables will be held in an array for easy access and organization.

```-- Add an array to manage enemy types
local alien_type_array = {
{ name="normal", speed=ALIEN_SPEED, 	life=5, green=200 }, 	-- Normal enemy
{ name="fast", 	 speed=ALIEN_SPEED / 2, life=2, green=255 },	-- Fast enemy weaker
{ name="slow",   speed=ALIEN_SPEED * 2, life=10, green=165 }}	-- slow enemy tougher```

make_alien()

You might make different enemy types based on different criteria or different situations. In this example to keep things simple I will make the choice of enemy type random. Each time an enemy is created I will choose a random type and configure the new enemy based on the information in the tables created above.

```-- Modify this function to select different types of aliens
local function make_alien()
local alien_type = alien_type_array[ math.random( 1, #alien_type_array ) ] -- Choose a random alien type

local alien = display.newRect( 0, 0, 32, 32 )
alien.alien_type = alien_type					-- Save the type
alien:setFillColor( 0, alien_type.green, 0 )	-- get the green value
local col = math.random( 1, TILE_COLS )
alien.col = col
alien.x = col * ( TILE_SIZE  + TILE_MARGIN )
alien.y = 0
alien.life = alien_type.life -- Get the life foe this type
alien.speed = alien_type.speed -- Save the speed

local t = alien_target_y * alien_type.speed -- Get the speed for this type
alien.transition = transition.to( alien, {y=alien_target_y, time=t, onComplete=remove_alien} )
alien_group:insert( alien )
table.insert( alien_array, alien )
end ```

Here we’re creating the enemies as before. The difference this time is that property values are set to starting values based on values found in the tables in the alien_type_array.

Last, since the speed can be set after an alien gets hit with a stun weapon, we should make sure the alien moves at it’s types speed after it is hit with a stun weapon. Look at check_bullets() function.

```local function check_bullets()
for b = 1, #bullet_array, 1 do
local bullet = bullet_array[b]
if b > #bullet_array then
return
end
for a = 1, #alien_array, 1 do
local alien = alien_array[a]
if hit_test( bullet.x, bullet.y, alien.contentBounds ) then
if alien.life > 0 then
alien.life = alien.life - bullet.damage
local defense_name = bullet.defense_name

if defense_name == "Stun" then
transition.cancel( alien.transition )
local t = ( alien_target_y - alien.y ) * alien.speed -- Use this aliens speed here

alien.transition = transition.to( alien, { y=alien_target_y,
time=t,
delay=300,
onComplete=remove_alien } )
end

else
remove_alien( alien )
end
remove_bullet( bullet )
break
end
end
end
end```

Here’s the full listing

## Corona – Tower Defense Game Experiments 11

So far we have the makings of a game but, there are more than a few that need to be taken care of. For example, the buttons do not show the energy cost. This makes it hard to play and test, since it’s hard to tell what the cost is for defenses.

### Groups as layers again

The buttons that I had created earlier were simple shapes. To show both text and a shape we need to create a group and add both elements to the group. Groups in Corona have all of the common display properties available to other display objects.

To make this work out I created a group for each button and used this to replace the original shape I had used for the button. Then I added the original rounded rectangle to the group. Then created a new Text shape and added that to the new group also.

I need to keep a reference to the rounded rectangle shape and text field. So I added properties to the group to hold these.

From here I retooled the rest of the script so all of the properties that had been attached to the button shape were now attached to the button_group. I also inserted the button_group into the defense_button_array in place of the original button shape. I also added the button_group into the control_group.

To get the costs to chose up in the text field I needed to get the cost from the defense_type_array for the current defense type and set it as the text of button_text.

Last I needed to adjust the positions of all three objects: button_group, button, and button_text.

```local function make_defense_buttons()
for i = 1, #defense_type_array, 1 do
local button_group = display.newGroup() -- Make a group to hold all button elements

local button = display.newRoundedRect( 0, 0, 40, 40, 6 )
local r = 255 * ( i / #defense_type_array )
button:setFillColor( r, 0, 0 )
button:setStrokeColor( 255, 255, 255 )
defense_type_array[i].red = r

local button_text = display.newText( "0", 0, 0, native.systemFontBold, 14 ) -- make a text field
button_text.text = defense_type_array[i].cost -- Display the cost
button_text.x = 20	-- Set the position of the label
button_text.y = 20	-- Set the position of the label

button_group:insert( button ) 		-- Add button shape to group
button_group:insert( button_text ) 	-- Add text to group

button_group.shape = button -- add button shape as a property to group
button_group.label = button_text -- add button text as property of group

-- Assign these properties to button group
button_group.index = i
button_group.x = display.contentWidth - 45 -- adjust the position
button_group.y = 40 + ( i * 50 )

table.insert(defense_button_array, button_group ) -- Add button group to array
control_group:insert( button_group ) -- add button group to control group
end
end```

The select_defense_button() function needs a little work also. This function needs to now set the stroke of the shape rather than the button. After the changes above the button will be a group rather than a shape.

```local function select_defense_button()
for i = 1, #defense_button_array, 1 do
local button = defense_button_array[i]
if button.index == current_defense_type then
button.shape.strokeWidth = 3 -- set the stroke of the shape
else
button.shape.strokeWidth = 0 -- set the stroke of the shape
end
end
end```

Showing disabled buttons

If a defense is not available to a player, due to not having enough energy to meet the cost, it should display as disabled. For this example I’ll make buttons that are disabled appear transparent. When a button is available it will be opaque.

Add a new function to handle this above touch_defense_button(). This new function will loop through each button in the defense_button_array and compare it’s cost to the current energy value and set it’s alpha accordingly.

```-- *** Add a new function to enable and disable buttons based on energy available
local function enable_disable_buttons()
for i = 1, #defense_button_array,1 do
local button = defense_button_array[i]
local cost = button.cost
if cost < energy then
button.enabled = true
button.alpha = 1.0
else
button.enabled = false
button.alpha = 0.5
end
end
end ```

To set up the initial state for these buttons we should call on this function when the game begins. Place a call below make_defense_buttons().

`enable_disable_buttons()`

Last, when the energy value changes we need to update the buttons to show a new state. Find the energy_recharge() function and add a call to enable_disable_buttons() there.

```local function energy_recharge()
energy = energy + ENERGY_RECHARGE_RATE
enable_disable_buttons() -- *** Update buttons
update_energy()
end>```

This works here but might need to be rethought if the recharge rate were slower.

Here's a full listing of the code

## Corona – Tower Defense Game Experiments 10

Giving the player the ability to place different types of defenses adds interest to the game. It opens up different types of strategies and different types of game play.

Looking at Plants vs Zombies you will see a wide variety of defense types. Here’s a list of the types of plants available: http://plantsvszombies.wikia.com/wiki/Gallery_of_Plants

Defenses can have a variety of features. Core ideas might be:

• Damage – how much damage the defense applies to an enemy
• Rate of fire – how often the defense fires
• Special effect – A special ability only applied to this type of defense
• Cost – The energy cost to place the defense

Really you could boil the list down cost vs power. This is the essential formula that creates balance and inspires game play. All of the features, except cost, are a measure of power for a defense. Cost is the balancing factor. Energy is collected over time, gives players the choice to build fewer more expensive defenses, or more less powerful defenses, or build a mix of each.

The key factor to making the game playable is a balance of cost vs power. Adding a mix of special features add a lot of interest to the game, provided the special features work well in cost vs power balance. As the programmer you can make anything happen. You can make the most powerful weapons cost very little. But this makes for an uninteresting playing experience. As a game design this is where you your real work. Finding the right balance of cost vs power for each element while providing some interesting effects.

In the example here I’ll keep the features simple. each defense will have a rate of fire, damage, and a cost.

Rate of fire will set the interval, in milliseconds, between shots for a defense.

Damage will determine how much subtracted from an enemies life property with each hit.

Cost sets the amount of energy that is paid to create this type of defense.

I’ve also added one special feature. One type of defense will also momentarily stop an approaching alien.

### defense_type_array

This array will hold a description of each defense type. With properties holding values for each of the features above. Here’s an example:

`{name="Standard",	rof=1000,	damage=1,	cost=50}`

This is standard defense, it all of the features of the original defense. It fires once every 1000 ms, it subtracts 1 from the life of an enemy with each hit, and costs 50 energy to create.

The name property will be used for special abilities.

I created an array of these tables named defense_type_array:

```local defense_type_array = {
{name="Standard",	rof=1000,	damage=1,	cost=50},
{name="Rapid",		rof=800,	damage=1,	cost=75},
{name="Heavy",		rof=2000,	damage=3,	cost=100},
{name="Stun",		rof=1200,	damage=0.5,	cost=80}
}```

There will be one button for each of items in this array.

We need to be able to identify each defense placed on the board. So far I haven’t used any graphics, so there isn’t a picture for each, yet. For now I will match the color of the button to the color of the defense. When the buttons are created I generate a color for each. As a temporary measure I will put the color in the defense type tables for easy reference.

In the make_defense_button() function add the following:

```local function make_defense_buttons()
for i = 1, #defense_type_array, 1 do
local button = display.newRoundedRect( 0, 0, 40, 40, 6 )
local r = 255 * ( i / #defense_type_array )

-- For this example I'll put the red values in each of these tables
-- this way we can color each of the defense elements to match the buttons.
defense_type_array[i].red = r

button.index = i
button:setFillColor( r, 0, 0 )
button:setStrokeColor( 255, 255, 255 )
button.x = display.contentWidth - 26
button.y = 40 + ( i * 50 )
table.insert(defense_button_array, button )
control_group:insert( button )
end
end```

### touch_tile()

Touching a tile creates a new defense. This is also where we check the available energy and pay the cost for the defense.

```local function touch_tile( event ) -- Check the type of defense
local phase = event.phase
if phase == "began" then
local tile = event.target
local tile_x = tile.x
local tile_y = tile.y

local cost = defense_type_array[current_defense_type].cost -- Get the cost for this defense type

if energy >= cost then -- Use cost here
energy = energy - cost -- and here
local defense = make_defense( tile_x, tile_y )
defense.col = tile.col
end
end
end```

### make_defense()

Each defense will now have a type and each will have different abilities. Each defense should keep track of it’s features: roy, damage and defense_name.

As an alternative, each defense could hold a reference to the table describing the defense features. Here I chose the first option. If there were many defense features the second option might be better.

```local function make_defense( x, y )
local defense = display.newRect( 0, 0, 32, 32 )

-- Get all of the properties describing this weapon and store them in the new defense
defense.rof 		 = defense_type_array[current_defense_type].rof
defense.damage 		 = defense_type_array[current_defense_type].damage
defense.defense_name = defense_type_array[current_defense_type].name
defense.red 		 = defense_type_array[current_defense_type].red

defense:setFillColor( defense.red, 0, 0 )
defense_group:insert( defense )
defense.x = x
defense.y = y
table.insert( defense_array, defense )
defense.timer = timer.performWithDelay( defense.rof, function() defense_defend( defense ) end, -1 )
return defense
end```

Here I just transferred the features across and set them as properties of the defense that was created. Notice that I also got the red property and used this to set the color of the defense. The defense should now match the color of button. Later when images are added we can dump the color.

### make_bullet()

Bullets created earlier were all the same. Now we want them to have unique properties described by the defense that fired them. The make_bullet() function doesn’t have a reference to the defense. But, it is called from the defense_defend() function that does have a reference to the defense. To share information between the two I’ll have make_bullet() return a reference to the bullet.

```local function make_bullet( x, y )
local bullet = display.newCircle( 0, 0, 5 )
bullet:setFillColor( 0, 0, 0 )
bullet.x = x
bullet.y = y
table.insert( bullet_array, bullet )

local bt = y * BULLET_SPEED
bullet.transition = transition.to( bullet, {y=0, time=bt, onComplete=remove_bullet} )
return bullet -- better return the bullet so the defense_defend() function can work with it
end```

### defense_defend()

The defense_defend() function creates bullets. Each bullet will need to know it’s damage value. To get the damage we need to have a reference to the defense. Here we get the bullet that was returned and assign it the damage and the name of the defense type that fired it. The name is important since I’ll use it for special effects.

Damage is easy, instead of subtracting 1 from alien.life. Here we replace this with bullet.damage. In this way each bullet can subtract it’s own damage value.

Next we need to check the defense_name. If the name is “Stun” I need to stop the enemy, and then start again after a short delay. Since the movement is handled by a transition we need to cancel the previous transition. Then add a new transition with a delay. Here I used the ALIEN_SPEED constant to make sure the enemy is moving at the same speed.

To get the speed right I needed to know the distance. To get the remaining distance to move the enemy I subtracted the current y from the alien_target_y value.

```local function defense_defend( defense )
for i = 1, #alien_array, 1 do
local alien = alien_array[i]
if alien.col == defense.col then
local bullet = make_bullet( defense.x, defense.y ) -- Get the bullet
bullet.damage = defense.damage 	-- assign a damage value to the bullet
bullet.defense_name = defense.defense_name 		-- get the name of the defense
break
end
end
end```

### make_alien()

I want to add a weapon with a special feature. One of the weapons will “Stun” an enemy. This will have the effect of stopping the enemy momentarily. To make this effect happen the current transition will have to be removed from the enemy and replaced with a new transition. The new transition will have a delay.

The challenge here is making the enemy continue moving at the same speed to the same end point as before it was stopped. To make this happen I need to know the end point, and know the rate of movement.

The end point for enemies was calculated in the make_alien() function previously. To make things more organized and efficient I defined a variable to hold the ending y value for enemies.

`local alien_target_y = ( TILE_SIZE + TILE_MARGIN ) * TILE_ROWS -- Ending y value for aliens`

This would need to be defined after TILE_SIZE, TILE_MARGIN and TILE_ROWS are defined. This value will probably not change, so it could have be declared as a constant I suppose.

Enemies will also need a rate of movement in px per sec. I defined this at the top as a constant.

`local ALIEN_SPEED = 1000 / 20 	-- Assign an alien speed 20px per sec`

Multiplying this by the distance will give us the time in ms that enemies will move at a rate of 20 px per sec.

Now we need to retool the make_alien function() to make use of these new variables.

```local function make_alien()
local alien = display.newRect( 0, 0, 32, 32 )
alien:setFillColor( 0, 200, 0 )
local col = math.random( 1, TILE_COLS )
alien.col = col
alien.x = col * ( TILE_SIZE  + TILE_MARGIN )
alien.y = 0
alien.life = 5
-- Change the alien movement
local t = alien_target_y * ALIEN_SPEED
alien.transition = transition.to( alien, {y=alien_target_y, time=t, onComplete=remove_alien} )
alien_group:insert( alien )
table.insert( alien_array, alien )
end```

Since enemies start at y of 0. The distance then move is alien_target_y. Multiply this by the ALIEN_SPEED and we get the time in ms for the transition. Notice that I removed some of the other code that was here from the previous example.

### check_bullet()

This function checks for bullets hitting enemies. We need to add two new features here: apply damage for specific bullet/defense types, and any special features for any specific bullet type. In this example only the “Stun” type defense will have a special effect.

The

```local function check_bullets()
for b = 1, #bullet_array, 1 do
local bullet = bullet_array[b]
if b > #bullet_array then
return
end
for a = 1, #alien_array, 1 do
local alien = alien_array[a]
if hit_test( bullet.x, bullet.y, alien.contentBounds ) then
if alien.life > 0 then
alien.life = alien.life - bullet.damage -- Use the damage value of the bullet
local defense_name = bullet.defense_name -- Get the name of the defense
-- Check the defense name and apply special stuff
if defense_name == "Stun" then
transition.cancel( alien.transition ) 				 -- Cancel the current transition
local t = ( alien_target_y - alien.y ) * ALIEN_SPEED -- Calculate a new speed
-- Add a new transition with a delay
alien.transition = transition.to( alien, { y=alien_target_y,
time=t,
delay=300,	-- Delay
onComplete=remove_alien } )
end

else
remove_alien( alien )
end
remove_bullet( bullet )
break
end
end
end
end```

Here’s a listing of the entire code used so far.

## Corona – Tower Defense Game Experiments 9

With one type of defense the only choice a player has is where to place a defense. Providing a choice of defense types gives players a chance to try different strategies. Plants vs Zombies provides a wide range of defense types each with a range of effects and cost.

As a first step to getting different types of defenses to work I need to have an interface to choose the type of defense to place. I don’t want to get into a long discussion what the best type of interface might be. The goal for this post will be to make a simple set of buttons that will act like a radio button group. Tapping one button will select it and deselect the currently selected button. Only one button can be selected at a time.

This idea could be applied to many other projects!

## The buttons

The buttons will be rounded rectangles filled with a color. I’ll use a white stroke to show which is selected.

## List types of defenses

The types of defense will be stored in an array. Knowing how many different types of defenses are available will tell us how many buttons to make.

For now the types of defenses can be anything. Later I will look at the features of each defense type and we can store that information. For now this array can store anything as long as there one element for each type. in the example I used the letters: “A”, “B”, “C” etc.

## Keeping track of the current defense type

I added a new variable: current_defense_type. This variable holds the index of the current defense type in the defense_type_array. For example if the current defense type is “B”, then current_defense_type would be 2.

`local current_defense_type = 1 -- marks the current defense type, matches the index of the defense type in the defense_type_array`

## List of buttons

The buttons will also be stored in an array. This is essential for keeping track of the buttons. Having an array of the buttons will make it easy to select and deselect any of the buttons in the array.

```local defense_type_array = {"A","B","C","D"} -- Make an array to keep track of defense buttons
local defense_button_array = {} -- use an array to keep track of buttons```

## The functions

I used three functions make_defense_buttons(), touch_defense_button(), and select_defense_button().

### make_defense_buttons()

This function makes the defense buttons. It makes one button for each item in the defense_type_array. Each button is given a different shade of red, and a white stroke. The buttons are also assigned the property index. This property is the index of the defense type in the defense_type_array that the button corresponds to. I also added a touch event to each button that is handled by touch_defense_button().

### touch_defense_button()

This function gets the index from the button and sets current_defense_type to this value. Then it calls select_defense_button().

### select_defense_button()

This function highlights the current button by setting the stroke width to 3 for that button and the stroke width of the other buttons to 0.

```-- Select the current button
local function select_defense_button()
for i = 1, #defense_button_array, 1 do
local button = defense_button_array[i]
if button.index == current_defense_type then
button.strokeWidth = 3
else
button.strokeWidth = 0
end
end
end

-- Handle button events
local function touch_defense_button( event )
local button = event.target
current_defense_type = button.index
select_defense_button()
end

-- Add a function to create defense buttons
local function make_defense_buttons()
for i = 1, #defense_type_array, 1 do
local button = display.newRoundedRect( 0, 0, 40, 40, 6 )
local r = 255 * ( i / #defense_type_array )
button.index = i
button:setFillColor( r, 0, 0 )
button:setStrokeColor( 255, 255, 255 )
button.x = display.contentWidth - 26
button.y = 40 + ( i * 50 )
table.insert(defense_button_array, button )
control_group:insert( button )
end
end

-- Call the function to make the buttons
make_defense_buttons()
-- Select the current defense type
select_defense_button()```

Here’s a full listing of the code so far:
Continue reading Corona – Tower Defense Game Experiments 9

## Corona – Tower Defense Game Experiments 8

A key factor to the tower defense game is the economy. If there is no limiting factor to how fast defenses can be created there isn’t much challenge since a player can quickly fill the board with defenses.

There needs to be a limiting factor in how often a player can place a defense. Here I will set up a simple system with an energy value that increases over time and incur an energy cost for placing defenses.

The key to making this system form an interesting game is balancing all of the factors. All of the factors need to be considered. Here’s a list:

• Speed of enemies – Faster enemies are harder to deal with
• Speed of bullets – Faster bullets can take care of closer range enemies before a defense is destroyed
• Defense rate of fire – Defenses that fire faster are more powerful
• Energy cost to place a defense – Lower cost allows defense to be placed more often
• Energy Recharge rate – The faster your energy recharges the more often you can place a defense

Note: Setting a cap on total available energy would be another idea to interest to game play. I didn’t do that here but it would not be hard to add.

This example will add a variable to track energy. Energy will recharge over time at a fixed rate. Placing a defense incurs an energy cost.

First I added a few constants at the top of the script to set fixed values.

Energy recharge rate sets the amount of energy is added each timer the energy timer updates. Energy defense cost sets the value subtracted from energy each time a defense is placed. Energy timer time sets the time in milliseconds that energy is recharged, added to energy.

```local ENERGY_RECHARGE_RATE = 1 -- Set the rate to recharge
local DEFENSE_ENERGY_COST = 50 -- Set the cost for a defense
local ENERGY_TIMER_TIME = 150	-- Timer to recharge energy```

We also need a few variables to keep track of energy and timers. Energy holds your current energy. Energy timer holds a reference to the timer that updates energy.

Note, I moved the alien timer to the top of my script to keep all of the timers together. This variable is not new.

```local alien_timer 	-- Moved this to the top
local energy_timer 		-- reference the energy timer
local energy = 0 		-- set the starting energy```

I needed a text field to display the current energy value. I defined this at the top since it might be accessed from any where.

`local energy_text -- Declare a text field to display energy`

I thought it might be good to have the energy display and other UI elements in their own group. So I added a group to hold these:

`local control_group = display.newGroup() -- Add a group for UI stuff`

Next I need to add a function to update the energy display, and a function to increase the energy value. I separated these into two functions thinking it might be more flexible in the future if I need to include code to position and adjust the position of the text field with each update.

The update_energy() function displays the current energy value in the text field.

The energy_recharge() function increase the energy value, then calls update_energy() to refresh the display.

In this arrangement the energy display is only updated when energy is increased. This works if the energy recharge rate is not too slow. If the recharge rate is slow you you could place a defense and not see the energy value update until the recharge timer updates energy. If this is effecting you, add a call to update_energy() to make_defense().

Last I added create the energy timer. Here we create a new timer that updates at the rate set by ENERGY_TIMER_TIME. With each update it calls energy_recharge(), and loops forever.

```local function update_energy()
energy_text.text = energy
end

local function energy_recharge()
energy = energy + ENERGY_RECHARGE_RATE
update_energy()
end

energy_timer = timer.performWithDelay( ENERGY_TIMER_TIME, energy_recharge, -1 ) ```

Last, I need to incur the energy cost for placing a defense element. Basically this means checking that there is sufficient energy to pay for a defense. If there is sufficient energy, subtract the cost from energy and create the defense.

New defense elements are created in the touch_tile() handler. Here I added a little logic to check the energy, subtract the energy cost and place the new defense.

```local function touch_tile( event )
local phase = event.phase
if phase == "began" then
local tile = event.target
local tile_x = tile.x
local tile_y = tile.y
if energy >= DEFENSE_ENERGY_COST then 		-- Check the energy
energy = energy - DEFENSE_ENERGY_COST	-- Pay energy for defense
local defense = make_defense( tile_x, tile_y )
defense.col = tile.col
end
end
end```

Still the game is lacking many features that would make it truly interesting to play. That said, what we have here is an outline of the mechanics that cover many of the elements that make the game function. Building on these ideas, adding compelling art, and a theme is what will make the game interesting.

Here’s the full source code

## Corona – Tower Defense Game Experiments 7

Time for the enemies to strike back. So far the defenses have it easy, there is no way to remove a defense. There are a lot of things we can do here. In this example I’ll just take a simple step and remove a defense if an enemy intersects it. This will let the game play and tutorial advance slowly. I find I get better results if I build things from smaller steps.

The first step here will be to check if an enemy is intersecting a defense. The earlier hit_test(x,y, bounds) function works well with bullets which are small size. With larger elements the center point of an object may be outside of another object, but the two objects might be overlapping still. To solve this we can use a different type of hit test comparing the bounds of both objects.

Here’s a simple function that tests for overlapping boundaries. This was posted here by jhocking: http://developer.anscamobile.com/code/flashs-hittestobject-emulated-using-contentbounds. I modified the function slightly but it is essentially the same.

```local function hit_test_bounds( bounds1, bounds2 )
return bounds1.xMin < bounds2.xMax
and bounds1.xMax > bounds2.xMin
and bounds1.yMin < bounds2.yMax
and bounds1.yMax > bounds2.yMin
end ```

This uses the boundaries of an object. imagine the boundary as a rectangle that just fits the object.

Now we need check for overlap between aliens and defense elements. For this we’ll need to loop through the alien_array and use the function above to check for an overlap with each of the defenses in defense_array. On a true from hit_test_bounds() remove that defense and break the loop.

```local function check_enemies()
for a = 1, #alien_array, 1 do
local alien = alien_array[a]

for d = 1, #defense_array, 1 do
local defense = defense_array[d]
-- Here we're use the new hit_test_bounds() function to check if the defense and alien overlap
if hit_test_bounds( alien.contentBounds, defense.contentBounds ) then -- Check for collision
remove_defense( defense )	-- Remove this defense on a collision
break
end
end
end
end```

Add a call to this function in the enterFrame. Have to check this each frame.

```local function on_enterframe( event )
check_bullets()
check_enemies()
end```

Remember, when creating a defense a timer is added which fires a bullet from the position of the defense. If the defense is removed it’s timer should also be removed. Update remove_defense():

```local function remove_defense( defense )
local index = table.indexOf( defense_array, defense )
timer.cancel( defense.timer )	-- Must remove the timer!
table.remove( defense_array, index )
display.remove( defense )
end ```