Raycasting

This commit is contained in:
MaddoScientisto 2024-04-29 23:32:40 +02:00
commit a352a671b9
3 changed files with 184 additions and 49 deletions

View file

@ -58,6 +58,7 @@ local weapons_manager = require(make_path("weapons"))
local Barrel = require(make_path("barrel"))
local Strawberry = require(make_path("strawberry"))
local Box = require(make_path("box"))
local NPC = require(make_path("npc"))
include(make_path("pgui" .. ".lua"))
@ -115,7 +116,8 @@ actors_db = {
{name="player",sprite=65,actor=nil},
{name="box",sprite=4,actor=Box},
{name="alarm",sprite=19,actor=nil},
{name="fan",sprite=16,actor=nil}
{name="fan",sprite=16,actor=nil},
{name="NPC",sprite=69,actor=NPC}
}
@ -307,3 +309,66 @@ function check_collisions()
end
function raycast(x1, y1, x2, y2, max_distance)
local dx = x2 - x1
local dy = y2 - y1
local step_x = dx > 0 and 1 or -1
local step_y = dy > 0 and 1 or -1
dx = dx < 0 and -dx or dx
dy = dy < 0 and -dy or dy
local fraction = dx - dy
local x = x1
local y = y1
-- calculate the distance between start and end point
local distance = (math.sqrt((x2-x1)^2 + (y2-y1)^2))\1
local scale = max_distance / distance
local px = x1 + (x2 - x1) * scale
local py = y1 + (y2 - y1) * scale
-- limit the maximum distance
if distance > max_distance then
--return x2, y2, false
return px, py, false
end
-- checking the start point
--if map_manager.is_tile_shoot_solid(flr(x / tile_width), flr(y / tile_height)) then
if map_manager.is_tile_shoot_solid(x, y) then
return x1, y1, false
end
local distance_traveled = 0
while distance_traveled <= max_distance and (x ~= x2 or y ~= y2) do
local prevX = x -- store previous positions for distance calculation
local prevY = y
if fraction >= 0 then
x += step_x
fraction -= dy
else
y += step_y
fraction += dx
end
-- calculate distance traveled
distance_traveled += math.sqrt((x - prevX) ^ 2 + (y - prevY) ^ 2)\1
-- return false as soon as a solid tile is hit
if map_manager.is_tile_shoot_solid(x, y) then
if x==x2 and y==y2 then -- return true only if hit tile is destination tile
return x, y, true
else
return x, y, false
end
end
end
-- if the loop is done without hitting a solid tile, return false
return x2, y2, true
end