# How to attach turrets to tiles in a tile based game

I am a flash developer, and I am building a Tower Defense game. The world is being built through tiles, and I have gotten that accomplished easily. I have also gotten level changes and enemy spawning down as well. However, I wish the player to be able to spawn turrets, and have those turrets be on specific tiles, based upon where the player placed it. Here is my code:

stop();

colOffset = 50;
rowOffset = 50;
guns = [];
placed = true;
spawned = 0;
level = 1;
interval = 350 / level;
amount = level * 20;
counter = 0;
numCol = 14;
numRow = 10;
tiles = [];
k = 0;
create = false;
board = new Array(
new Array(1,1,1,1,3,1,1,1,1,1,2,1,1,1),
new Array(1,1,1,0,0,1,1,1,1,1,0,1,1,1),
new Array(1,1,1,0,1,1,1,1,1,1,0,0,1,1),
new Array(1,1,1,0,0,0,1,1,1,1,1,0,1,1),
new Array(1,1,1,0,1,0,0,0,1,1,1,0,0,1),
new Array(1,1,1,0,1,1,1,0,0,1,1,1,0,1),
new Array(1,1,0,0,1,1,1,1,0,1,1,0,0,1),
new Array(1,1,0,1,1,1,1,1,0,1,0,0,1,1),
new Array(1,1,0,0,0,0,0,0,0,1,0,1,1,1),
new Array(1,1,1,1,1,1,1,1,0,0,0,1,1,1)

);

buildBoard();
function buildBoard(){
for ( col = 0; col < numCol; col++){
for ( row = 0; row < numRow; row++){
_root.attachMovie("tile", "tile_" + col + "_" + row, _root.getNextHighestDepth());
theTile = eval("tile_" + col + "_" + row);
theTile._x = (col * 50);
theTile._y = (row * 50);

theTile.row = row;
theTile.col = col;

tileType = board[row][col];

theTile.gotoAndStop(tileName[tileType]);
tiles.push(theTile);

}

}

}

init();

function init(){
onEnterFrame = function(){
counter += 1;
if ( spawned < amount && counter > 50){
min= _root.attachMovie("minion","minion",_root.getNextHighestDepth());
min._x = tile_4_0._x + 25;
min._y = tile_4_0._y + 25;
min.health = 100;
choose = Math.round(Math.random());
if ( choose == 0 ){
min.waypointX = [ tile_4_1._x +25, tile_3_1._x + 25, tile_3_2._x + 25, tile_3_6._x + 25, tile_2_6._x + 25, tile_2_8._x + 25, tile_8_8._x + 25, tile_8_9._x + 25, tile_10_9._x + 25, tile_10_7._x + 25, tile_11_7._x + 25, tile_11_6._x + 25, tile_12_6._x + 25, tile_12_4._x + 25, tile_11_4._x + 25, tile_11_2._x + 25, tile_10_2._x + 25, tile_10_0._x + 25];
min.waypointY = [ tile_4_1._y +25, tile_3_1._y + 25, tile_3_2._y + 25, tile_3_6._y + 25, tile_2_6._y + 25, tile_2_8._y + 25, tile_8_8._y + 25, tile_8_9._y + 25, tile_10_9._y + 25, tile_10_7._y + 25, tile_11_7._y + 25, tile_11_6._y + 25, tile_12_6._y + 25, tile_12_4._y + 25, tile_11_4._y + 25, tile_11_2._y + 25, tile_10_2._y + 25, tile_10_0._y + 25];
}
else if ( choose == 1 ){
min.waypointX = [ tile_4_1._x +25, tile_3_1._x + 25, tile_3_2._x + 25, tile_3_3._x + 25, tile_5_3._x + 25, tile_5_4._x + 25, tile_7_4._x + 25, tile_7_5._x + 25, tile_8_5._x + 25, tile_8_8._x + 25, tile_8_9._x + 25, tile_10_9._x + 25, tile_10_7._x + 25, tile_11_7._x + 25, tile_11_6._x + 25, tile_12_6._x + 25, tile_12_4._x + 25, tile_11_4._x + 25, tile_11_2._x + 25, tile_10_2._x + 25, tile_10_0._x + 25 ];
min.waypointY = [ tile_4_1._y +25, tile_3_1._y + 25, tile_3_2._y + 25, tile_3_3._y + 25, tile_5_3._y + 25, tile_5_4._y + 25, tile_7_4._y + 25, tile_7_5._y + 25, tile_8_5._y + 25, tile_8_8._y + 25, tile_8_9._y + 25, tile_10_9._y + 25, tile_10_7._y + 25, tile_11_7._y + 25, tile_11_6._y + 25, tile_12_6._y + 25, tile_12_4._y + 25, tile_11_4._y + 25, tile_11_2._y + 25, tile_10_2._y + 25, tile_10_0._y + 25 ];

}
min.i = 0;

counter = 0;
spawned += 1;

min.onEnterFrame = function(){
dx = this.waypointX[this.i] - this._x;
dy = this.waypointY[this.i] - this._y;
degrees = radians * 180 / Math.PI;

this._x += xspeed;
this._y += yspeed;

if( this._x == this.waypointX[this.i] && this._y == this.waypointY[this.i]){
this.i++;
}
if ( this._x == tile_10_0._x + 25 && this._y == tile_10_0._y + 25){
this.removeMovieClip();

}

}

}
if ( dead >= amount ){

level += 1;
amount = level * 20;
spawned = 0;

}
}
btnM.onRelease = function(){
create = true;
}

}

game.onEnterFrame = function(){

}


It is possible for me however to complete this task, but only once. I am able to make the turret, drag it over to a tile, and have it attach itself to the tile. No problem. The issue is, I cannot do these multiple times. Please Help.

• That's way too much code for a question like this. Also the creation of the turret doesn't seem to be included in the code at all? – bummzack Nov 25 '11 at 13:40
• Is this... Actionscript 2? Oh not this again... use Actionscript 3, AS2 is outdated and teaches bad practices. – user4248 Nov 25 '11 at 15:43

It seems you save the world in a two dimensional array. Why not save the turret positions in another two dim array the same size? When you draw the level you iterate over both arrays and draw the contents of the arrays in the right order, ie the level first and then the turret.

• Expensive for memory. – Triang3l Nov 26 '11 at 18:09
• @SiPlus, Considering the level size is relatively small, memory isn't really an issue. Assuming a 4 byte pointer/reference size, we're talking 560bytes of memory per array. Doing unnecessary preoptimizations are the root to all evil. – William Mariager Nov 26 '11 at 19:05
• The 2nd array could even use negative values to prevent building/placing towers in a certain location independend of the terrain tile used. – Exilyth Nov 27 '11 at 6:38

Use bitwise operators and store numbers created using bitwise OR (operator |) in your array. This technique is called "flags".

For example, let's define the following hexadecimal numbers:

• grass = 0x0002
• end = 0x0004
• start = 0x0008
• free = 0x0100
• turret = 0x0200
• snipertower = 0x0400
• howitzer = 0x0800

Then, to create an empty grass tile, you need to store number (grass | free) in your array "board" at the position of the tile. If you want to create road tile with sniper tower, store (road | snipertower) in your array.

If you want to retrieve type of the tile and the object on it, you need to use bitwise AND operator (&). It will give a number if bits of compared numbers match, and 0 if bits of compared numbers don't match. For example, if you want to know, do you have howitzer on your tile, you need to AND the tile (stored in array) with number "howitzer" (0x0800). If you have howitzer on the tile, you'll get a number, and if you don't, you'll get 0. To get do you have grass on your tile, you need to AND the tile with "grass" (0x0002 or 0x02, doesn't matter), and, as I said before, if you have grass on your tile, you'll get some number, and if you don't, you'll get 0.

Code example (written in JavaScript, I don't know ActionScript):

var board = new Array(
new Array(0x0108, 0x0101, 0x0101, 0x0101), //road from start
new Array(0x0102, 0x0102, 0x0102, 0x0101), //grass with already spawned snipers @ x3
new Array(0x0101, 0x0101, 0x0101, 0x0101), //just road
new Array(0x0104, 0x0102, 0x0102, 0x0102)); //end at x1
function getTypeOfBlock(x,y)
{
var tile = board[y][x]; //optimization
if (tile & 0x08) //is start?
return 'start';
else if (tile & 0x04) //is end?
return 'end';
else if (tile & 0x02) //is grass?
return 'grass';
else
}
function buildTurret(x,y)
{
if (!board[y][x] & 0x0100) //check is the tile free - gives 0 (false) if it's occupied
return; //don't do anything
board[y][x] | 0x0200; //build turret at position
}


Warnings:

• All byte values must be 1 or power of 2.
• Never OR or AND with number 0, it will give 0.
• You can't have more than 8 hex. digits in 32-bit flag (integer) or 16 digits in 64-bit flag.