LUA 2d Line of sight

From RogueBasin
Revision as of 22:37, 25 December 2011 by Rustle (talk | contribs)
Jump to navigation Jump to search

Hi, I adapted this function to suit my roguelike from:

http://www.gamedev.net/reference/articles/article1275.asp code by Tom Ootjers

I made it go "one round further" when LOS was blocked, so my engine would draw the trees and monsters even though they blocked los.

The many comments are his, also. Credit goes to him basically. I got it to work on for roguelikes though.


function funcs.lineofsight(x1,y1,x2,y2)

local math = math

local deltax = math.abs(x2 - x1) -- // The difference between the x's

local deltay = math.abs(y2 - y1) -- // The difference between the y's

local x = x1; -- // Start x off at the first pixel

local y = y1; -- // Start y off at the first pixel

local xinc1,xinc2,yinc1,yinc2

if (x2 >= x1) then -- // The x-values are increasing

 xinc1 = 1;
 xinc2 = 1;

else -- // The x-values are decreasing

 xinc1 = -1;
 xinc2 = -1

end


if (y2 >= y1) then -- // The y-values are increasing

 yinc1 = 1;
 yinc2 = 1;

else -- // The y-values are decreasing

 yinc1 = -1;
 yinc2 = -1;

end


if (deltax >= deltay) then -- // There is at least one x-value for every y-value

 xinc1 = 0;               --   // Don't change the x when numerator >= denominator
 yinc2 = 0;              --    // Don't change the y for every iteration
 den = deltax;
 num = deltax / 2;
 numadd = deltay;
 numpixels = deltax;       --  // There are more x-values than y-values

else -- // There is at least one y-value for every x-value

 xinc2 = 0;                --  // Don't change the x for every iteration
 yinc1 = 0;                --  // Don't change the y when numerator >= denominator
 den = deltay;
 num = deltay / 2;
 numadd = deltax;
 numpixels = deltay;       --  // There are more y-values than x-values

end

local onemoreround = 0

local roundnum = 0

while (true) do

roundnum = roundnum + 1 --forces two distance sight

           --  // Draw the current pixel

if onemoreround == 1 and roundnum > 2 then return false end --this stuff is so it penetrates one round and doesnt stop on the first round

	if (roundnum ~= 1) and funcs.checkforlosblock(x,y) then onemoreround = 1 end --was return false

if x == x2 and y == y2 then return true end



num = num + numadd;              --// Increase the numerator by the top of the fraction
 if (num >= den) then           --  // Check if numerator >= denominator
   num = num - den;             --  // Calculate the new numerator value
   x = x +xinc1;             --  // Change the x as appropriate
   y = y+ yinc1;             --  // Change the y as appropriate
 end
 x = x+xinc2;               --  // Change the x as appropriate
 y = y+yinc2;               --  // Change the y as appropriate

end

end



function funcs.checkforlosblock(x,y)

          --enter your own checks here to see if the square is has any objects that would block LOS like trees, etc.  Those objects should just have "block_los" = true. Return true if square is blocked, false if its clear.

By User:Rustle