The final part of the 'Simple Math' line-of-sight function for a tile-based game. In part 1 we discussed only the very basic concepts of tile-based boards and created a couple of functions to return the coordinates of a tile. In part 2 we created a simple method to track where blocking objects sit on the board and a function to check if a particular tile has a blocking object. Now the only thing left to do is the LOS function itself.

#### Concept

From the player object, we will follow a direct line to the tile we want to check. As we follow this line to its destination point, if the line touches any tile that has a blocking object, then the LOS check should return that the vision from the player is blocked.

#### Line-of-Sight function

In this function we will send the (Col, Row) of the starting object (the player in this case) and the (Col, Row) of the tile we want to draw a line to. Just like the checkTileBlocking function, we will assume that the LOS is not blocked unless we find a tile with a blocking object on it.

function checkLOS(col1, row1, col2, row2)

{

hasLOS = true;

return hasLOS;

}

For this function we will need to determine how many times the function will check to see if the line crosses a tile. Obviously the more times we check a specific point on the line, the more accurate the LOS check will be. But if we get to crazy and check every millo-second we could really bog down the Flash player. So for this example we will check the line a number of times equal to double the max distance from one side of the board to the other. Since the board is 10 x 10, double the max is 20.

checkSteps = 20

Which is also:

checkSteps = colLength + rowLenth;

Because we are using 'simple math', good old algebra, we will need to convert these (Col, Row) coordinates that we sent to the function into (X, Y) coordinates. We will also need the slope of the line.

function checkLOS(col1, row1, col2, row2)

{

hasLOS = true;

checkSteps = colLength + rowLenth;

startXY = getCoords_XY(col1, row1);

endXY = getCoords_XY(col2, row2);

slopeX = (endXY.x - startXY.x) / checkSteps;

slopeY = (endXY.y - startXY.y) / checkSteps;

return hasLOS;

}

Now we need to loop through all of the steps it will take to get from the player to the end tile.

function checkLOS(col1, row1, col2, row2)

{

hasLOS = true;

checkSteps = colLength + rowLenth;

startXY = getCoords_XY(col1, row1);

endXY = getCoords_XY(col2, row2);

slopeX = (endXY.x - startXY.x) / checkSteps;

slopeY = (endXY.y - startXY.y) / checkSteps;

for(i = 0; i < checkSteps; i++)

{

currentX = startXY.x + (slopeX * i);

currentY = startXY.y + (slopeY * i);

currentTile = getCoords_ColRow(currentX , currentY);

}

return hasLOS;

}

Now that we have our line drawn, and the function knows which tiles the line crosses over, we will add a check to see if there is a blocking object on each of the tiles we are looking at.

function checkLOS(col1, row1, col2, row2)

{

hasLOS = true;

checkSteps = colLength + rowLenth;

startXY = getCoords_XY(col1, row1);

endXY = getCoords_XY(col2, row2);

slopeX = (endXY.x - startXY.x) / checkSteps;

slopeY = (endXY.y - startXY.y) / checkSteps;

for(i = 0; i < checkSteps; i++)

{

currentX = startXY.x + (slopeX * i);

currentY = startXY.y + (slopeY * i);

currentTile = getCoords_ColRow(currentX , currentY);

blockedTile = checkTileBlocking(currentTile.col, currentTile.row);

if(blockedTile)

{

hasLOS = false;

}

}

return hasLOS;

}

Technically the LOS function could be done, but we want to add one more check to the function. We don't want the line-of-sight to be considered blocked if the only blocking object is on the last tile we are checking.

function checkLOS(col1, row1, col2, row2)

{

hasLOS = true;

checkSteps = colLength + rowLenth;

startXY = getCoords_XY(col1, row1);

endXY = getCoords_XY(col2, row2);

slopeX = (endXY.x - startXY.x) / checkSteps;

slopeY = (endXY.y - startXY.y) / checkSteps;

for(i = 0; i < checkSteps; i++)

{

currentX = startXY.x + (slopeX * i);

currentY = startXY.y + (slopeY * i);

currentTile = getCoords_ColRow(currentX , currentY);

isBlockedTile = checkTileBlocking(currentTile.col, currentTile.row);

if(isBlockedTile AND (currentTile IS NOT (col2, row2)))

{

hasLOS = false;

}

}

return hasLOS;

}

#### Closing

This is a light weight and simple way of checking the LOS from one tile to another. If you need to optimize it further, implement the suggestion I made in the tracking of the blocking objects in Part 2.

Keep in mind that I created this LOS function for a somewhat small tile-based game. It's not really intended for a massive real-time tile-based game, I would be interested to hear of someone doing something similar to this in those kind of settings.