LUA 2d Line of sight

From RogueBasin
Revision as of 22:44, 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

It returns true if x1,y1 can "see" x2,y2 without "blockage" in the "line of sight" and "false" if otherwise, so in your LUA code it can be used like if funcs.lineofsight(x1,y1) then (draw the creature or shoot the arrow or whatever) end along with your other checks for the action.

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.


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