Raycaster Issues (Horizontal Checking)

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
NoreoAlles
Party member
Posts: 107
Joined: Mon Jan 03, 2022 5:42 pm

Raycaster Issues (Horizontal Checking)

Post by NoreoAlles »

Hi, i´ve been trying to make a Raycaster in Löve and i need help because (1) my rays are kindof cluttered and (2) my rays dont care if they´ve hit a wall sometimes and (3) the rays sometimes all go right when my player is facing left and near to a wall in the right direction.
I´ve tried to comment most of the stuff.
Any help would be appriciated :nyu:
Attachments
raycaster.love
(1.9 KiB) Downloaded 25 times
"Why do they call it oven when you of in the cold food of out hot eat the food?" - Jon Arbuckle
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

Re: Raycaster Issues (Horizontal Checking)

Post by Bigfoot71 »

There are a number of choices that I haven't really been able to understand in your code, so I took the liberty of completely rewriting the function to better understand the concept, here's what it might look like (I've part removed point storage in hits):

Code: Select all

function RayCast(ray_step_size, num_rays)

    num_rays = num_rays or screen_width
    ray_step_size = ray_step_size or 5

    local angle = P.a - fov / 2
    local step = fov / (num_rays - 1)

    love.graphics.setColor(1, 0, 0) -- We apply the line color only once

    for i = 1, num_rays do

        local sin_a = math.sin(angle)
        local cos_a = math.cos(angle)

        local x = P.x
        local y = P.y

        local distance_to_wall = 0
        local hit_wall = false

        while not hit_wall do

            local map_x = math.floor(x / tile_size) + 1 -- Round ray pos to map pos
            local map_y = math.floor(y / tile_size) + 1

            if map[map_y][map_x] == 1 then                                    -- If the step of the ray is in a wall
                distance_to_wall = math.sqrt((x - P.x) ^ 2 + (y - P.y) ^ 2)   -- We calculate the distance
                hit_wall = true  -- This value is used for understanding the code
                break            -- We could do without it since we break just after
            end

            x = x + cos_a * ray_step_size   -- Next raystep
            y = y + sin_a * ray_step_size

            if x < 0 or y < 0 or x > map_width * tile_size or y > map_height * tile_size then -- Security if you leave the map
                break
            end

        end

        -- Draw the red line to the nearest wall --

        local line_end_x = P.x + cos_a * distance_to_wall
        local line_end_y = P.y + sin_a * distance_to_wall
        love.graphics.line(P.x, P.y, line_end_x, line_end_y)

        -- We go to the next angle step (next ray) --

        angle = angle + step

    end

end
It's still a version that I also tweaked personally, there are many courses on raycasting that cover even more optimized techniques, but I think what I wrote is quite simple to understand, if you have any questions. don't hesitate.

Otherwise maybe someone more knowledgeable than me could say more because I don't want to lose you. When I'm gone I don't stop anymore :crazy:

Here is the result with ray_step_size = 0.1 (px) and ray_nums = 45:
Image

And the result with the default parameters, i.e. ray_step_size = 5 (px) and ray_nums = screen_width:
Image

(Don't pay attention to the FPS counter which varies a lot, I'm on an old machine and I was filming, without filming it remained rather stable for me)
Attachments
Raycasting.love
(1.93 KiB) Downloaded 18 times
My avatar code for the curious :D V1, V2, V3.
User avatar
NoreoAlles
Party member
Posts: 107
Joined: Mon Jan 03, 2022 5:42 pm

Re: Raycaster Issues (Horizontal Checking)

Post by NoreoAlles »

Thank you so much, that is so much cleaner then what i tried. I tried to skip the "extend ray by this size" part and tried to just do it super optimized without really understanding what i was doing. I´ll tell you if i have any more problems, but this just looks great. (:
"Why do they call it oven when you of in the cold food of out hot eat the food?" - Jon Arbuckle
User avatar
NoreoAlles
Party member
Posts: 107
Joined: Mon Jan 03, 2022 5:42 pm

Re: Raycaster Issues (Horizontal Checking)

Post by NoreoAlles »

I quickly made it render in 3d, thought you might want to see. I´ll later fix the fisheye and maybe make a full game out of this and post it here on the forums. I for now have copied your code exactly but i will ofc change it later on, hope you dont mind
Attachments
3d and 2d side to side.love
(1.84 KiB) Downloaded 20 times
Last edited by NoreoAlles on Tue Mar 28, 2023 4:01 pm, edited 2 times in total.
"Why do they call it oven when you of in the cold food of out hot eat the food?" - Jon Arbuckle
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

Re: Raycaster Issues (Horizontal Checking)

Post by Bigfoot71 »

NoreoAlles wrote: Tue Mar 28, 2023 3:08 pm Thank you so much, that is so much cleaner then what i tried. I tried to skip the "extend ray by this size" part and tried to just do it super optimized without really understanding what i was doing. I´ll tell you if i have any more problems, but this just looks great. (:
This code that I proposed remains as an example to fully understand the principle, I have kept it as simple as possible so as not to confuse you so it is very largely optimizable.

Besides the values ​​that are recalculated on each call to the function, you could also use a spatialization technique to limit the number of collision tests performed in each iteration of the loop. Something that looks technical said like that so I redirect you to this course which will explain it so much better than me, hoping that you are a little comfortable with C++ but it is the best course on raycasting that I have never found personally: https://lodev.org/cgtutor/raycasting.html

You don't have to reproduce the code shown exactly, at least understand what it says and you should be able to write your own code on your own. :)

By the way, this site contains a lot of very useful resources for graphic programming ^^

Edit:
NoreoAlles wrote: Tue Mar 28, 2023 3:50 pm I quickly made it render in 3d, thought you might want to see. I´ll later fix the fisheye and maybe make a full game out of this and post it here on the forums. I for now have copied your code exactly but i will ofc change it later on, hope you dont mind
Sorry I didn't see your answer, well done it's super cool! And no, it doesn't bother me at all, it's made for it, and if you improve it it's even better ^^
If you make a real game out of it, I really advise you to see the link I gave you to optimize and reduce the number of iterations of the while loop, it will be very useful for you to do something really clean!
Last edited by Bigfoot71 on Tue Mar 28, 2023 7:14 pm, edited 2 times in total.
My avatar code for the curious :D V1, V2, V3.
User avatar
darkfrei
Party member
Posts: 1168
Joined: Sat Feb 08, 2020 11:09 pm

Re: Raycaster Issues (Horizontal Checking)

Post by darkfrei »

Your code

Code: Select all

        if self.a > math.pi*2 then 
            self.a = 0
        end 
must be

Code: Select all

        if self.a > math.pi*2 then 
            self.a = self.a - math.pi*2
        end 
Maybe just this for both rotations (not tested):

Code: Select all

self.a = self.a%(math.pi*2)
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
Post Reply

Who is online

Users browsing this forum: No registered users and 16 guests