[SOLVED] How to make wall collision for 3 axis instead of 2?

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
Stepanchicko
Prole
Posts: 6
Joined: Thu May 09, 2024 3:54 pm
Location: Russia, Podolsk
Contact:

[SOLVED] How to make wall collision for 3 axis instead of 2?

Post by Stepanchicko »

Hi. I'm a newbie in LOVE2D, and I recently decided to make a custom 3d raycaster template for my future games. Everything in there works relatively fine, except for the fact I can't figure out how to make proper collision on the Z-axis.

For context, each block in my map has these coordinate values: X/Y/Z and W/H/D (d for depth). The Z value is the bottom of the block, the D value is its length until the very top. Finding out how to do proper wall collision for the 2 axis was not easy, but doable for me. However I didn't find a single piece of info on how to do it for 3 axis instead of 2. :emo: I'd be delighted and forever grateful if someone smart figured out how to do that in the LOVE2D nature. :awesome:

I've attached the .love file below. :3
Attachments
raycast.love
(2.91 KiB) Downloaded 128 times
Last edited by Stepanchicko on Fri Jun 14, 2024 7:15 pm, edited 3 times in total.
Stepanchicko
Prole
Posts: 6
Joined: Thu May 09, 2024 3:54 pm
Location: Russia, Podolsk
Contact:

Re: Collision for 3 axis instead of 2?

Post by Stepanchicko »

Update: I figured out the aabb collision (wasn't that hard) but I'm still struggling with the actual wall collision function. :emo:
Stepanchicko
Prole
Posts: 6
Joined: Thu May 09, 2024 3:54 pm
Location: Russia, Podolsk
Contact:

Re: How to make wall collision for 3 axis instead of 2?

Post by Stepanchicko »

I mean, I sort of figured it out, but it's kinda wanky. It doesn't work properly.

Code: Select all

function aabb(x1, y1, z1, w1, h1, d1, x2, y2, z2, w2, h2, d2)
    return x1 < x2+w2 and
           x2 < x1+w1 and
           y1 < y2+h2 and
           y2 < y1+h1 and
           z2 < z1+d1 and
           z1 < z2+d2
end

function collide(x1, y1, z1, w1, h1, d1, x2, y2, z2, w2, h2, d2)
    if not aabb(x1, y1, z1, w1, h1, d1, x2, y2, z2, w2, h2, d2) then
        return false, 0, 0, 0
    end
    local vx = x1 + w1 * .5 - x2 - w2 * .5
    local vy = y1 + h1 * .5 - y2 - h2 * .5
    local vz = z1 + d1 * .5 - z2 - d2 * .5
 
    vx = vx > 0 and x2 + w2 - x1 or x2 - x1 - w1
    vy = vy > 0 and y2 + h2 - y1 or y2 - y1 - h1
    vz = vz > 0 and z2 + d2 - z1 or z2 - z1 - d1
    local chosen = math.max(vx, vy, vz)
    local function eq_to(value, eq)
        if value ~= eq then return false else return true end
    end
 
    return true, eq_to(chosen, vx) and vx or 0, eq_to(chosen, vy) and vy or 0, eq_to(chosen, vz) and vz or 0
end
My player's z is always decreasing by 50 * dt and to prevent it from falling I set a floor at the bottom of the map. It doesn't let me fall down, but sometimes when I'm moving it just flings me all the way to its edge. Now the question is how do I fix it? :cry: :cry: :cry:

Here's the new .love file.
Attachments
raycast bebebe.love
(3.11 KiB) Downloaded 117 times
Stepanchicko
Prole
Posts: 6
Joined: Thu May 09, 2024 3:54 pm
Location: Russia, Podolsk
Contact:

Re: How to make wall collision for 3 axis instead of 2?

Post by Stepanchicko »

Nevermind! :awesome:
A generous man in Telegram helped me with this issue and it works just great! Here's the final code.

Code: Select all

function collide(x1, y1, z1, w1, h1, d1, x2, y2, z2, w2, h2, d2)
    if not aabb(x1, y1, z1, w1, h1, d1, x2, y2, z2, w2, h2, d2) then
        return false, 0, 0, 0
    end
    local vx = x1 + w1 * .5 - x2 - w2 * .5
    local vy = y1 + h1 * .5 - y2 - h2 * .5
    local vz = z1 + d1 * .5 - z2 - d2 * .5
 
    vx = vx > 0 and x2 + w2 - x1 or x2 - x1 - w1
    vy = vy > 0 and y2 + h2 - y1 or y2 - y1 - h1
    vz = vz > 0 and z2 + d2 - z1 or z2 - z1 - d1
    local xAxis, yAxis, zAxis = false, false, false
    if math.abs(vx) > math.abs(vy) then
        if math.abs(vy) > math.abs(vz) then
            zAxis = true
        else
            yAxis = true
        end
    else
        if math.abs(vx) > math.abs(vz) then
            zAxis = true
        else
            xAxis = true
        end
    end
    return true, xAxis and vx or 0, yAxis and vy or 0, zAxis and vz or 0
end
Funny how I was talking to myself the whole post :P
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 7 guests