Useful CS2D Lua Functions: Part II

Recently, I’ve been asked twice about how to check if there’s something obstructing the path from (x1;y1) to (x2;y2). Here I’ll provide two implementations equally useful – to check if there’s something obstructing the way for a player (wall or obstale) and to check if there’s something obstructing the way for a bullet (wall).

First, let’s use our handy function for moving objects forward (refer to this post). As will be demonstrated next, it’s not only used for that.

So, we inserted the function into the code – now let’s do the functions that check for obstructions.

[lua]
function checkfreepath(x1,y1,x2,y2)
local rot=-math.deg(math.atan2(x1-x2,y1-y2))
local cx,cy=x1,y1
while math.floor(cx/32)<=math.floor(x2/32) and math.floor(cy/32)<=math.floor(y2/32) do
if not tile(math.floor(cx/32),math.floor(cy/32),’walkable’) then
return false
end
cx,cy=angledir(rot,cx,cy,32)
end
return true
end
[/lua]

The function checkfreepath checks if the path for a player is free. It takes in four arguments – x1 and y1 are the coordinates of the initial position, and x2 and y2 are the coordinates of the terminal position.

It functions following this algorithm:

  1. Find the angle between the two positions
  2. Declare local variables for current X and Y
  3. Run a while loop to execute code while the current X and Y being checked aren’t beyond where we want it to check
  4. Check if the tile being checked is walkable – if it’s not, we end the function and return false
  5. Move the current position checked by 32 pixels (1 tile) forward
  6. If the function hasn’t ended already – meaning the path is free – return true

Pros and cons:

  • Pro: the while loop checks for floored positions divided by 32 and the angledir function moves the current position by 32 to increase efficiency
  • Con: the function accepts pixels as the coordinate measurement – with tiles supplied the function will not work

Knowing the big turndown of our function, we could make it versatile, adding a fifth argument being the mode of the function. The code would look like so:
[lua highlight=”2,3,6,7,10″]
function checkfreepath(x1,y1,x2,y2,tiles)
local f=1
if tiles then f=32 end
local rot=-math.deg(math.atan2(x1-x2,y1-y2))
local cx,cy=x1,y1
while math.floor(cx/f)<=math.floor(x2/f) and math.floor(cy/f)<=math.floor(y2/f) do
if not tile(math.floor(cx/f),math.floor(cy/f),’walkable’) then
return false
end
cx,cy=angledir(rot,cx,cy,f)
end
return true
end
[/lua]

As you can see, there are new lines as well as some minor changes on the highlighted lines. The factor now isn’t 32 – it’s f, which is a local variable we declared on line 2. On line 3, we check if tiles is specified – if the tiles argument is anything except nil and false, the factor automatically sets to 1, which means the measurement is tiles. Otherwise, the factor is set to 32, and the measurement becomes pixels.

Good luck!

Published by

EngiN33R

EngiN33R

Developer, linguistics enthusiast, amateur teacher. All opinions are my own.

One thought on “Useful CS2D Lua Functions: Part II”

  1. This really could be improved.
    Take the following (untested) code:
    http://www.cs2dinfo.com.ar/pastebin/index.php/view/45218860

    It drastically reduces the number of iterations
    (x1-x2)^2+(y1-y2)^2)^0.5 iterations vs math.max(x1-x2, y1-y2) iterations
    Remember that the hypotenuse is always greater than any of the cathetus.

    Moreover, it avoids using expensive functions such as sin() and cos()

    Of course, this method could have failed in cases where the path would be a vertical line, so I made it able to “invert” itself in those cases. When the vertical vector would be bigger than the horizontal one it should invert too to avoid missing any pixels that could be inside a tile.

Leave a Reply

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