Collision teleports rectangle to corner

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
Actravaz
Prole
Posts: 5
Joined: Sat May 21, 2022 6:16 pm

Collision teleports rectangle to corner

Post by Actravaz »

Hello folks. I'm trying to make a physics engine but whenever a rectangle hits the corner of another rectangle, it teleports to the other end of the hit rectangle. I'm not sure if it's anything wrong with my code or what.

Code: Select all

function collide(object)
    for i,v in ipairs(workspace) do
        if CheckCollision(object.xpos,object.ypos,object.x,object.y,v.xpos,v.ypos,v.x,v.y) and v ~= object then
            if object.olypos < v.ypos then
                if object.xpos > v.xpos and (object.xpos + object.x) < (v.xpos + v.x) then
                    object.vely = 0
                    object.ypos = object.olypos
                    object.ypos = (v.ypos - object.y)
                end
                
            end
            if object.olypos + object.y > v.ypos  then
                if object.xpos > v.xpos and (object.xpos + object.x) < (v.xpos + v.x) then
                    object.vely = 0
                object.ypos = object.olypos
                object.ypos = ((v.ypos + v.y))
                end
            end


            



            if object.olxpos < v.xpos then
                if object.ypos > v.ypos and (object.ypos + object.y) < (v.ypos + v.y) then
                    object.velx = 0
                    object.xpos = object.olxpos
                    object.xpos = (v.xpos - object.x)
                end
            end

            if object.olxpos + object.x > v.xpos then
                if object.ypos > v.ypos and (object.ypos + object.y) < (v.ypos + v.y) then
                    object.velx = 0
                object.xpos = object.olxpos
                object.xpos = ((v.xpos + v.x))
                end
            end
        end
    end
end
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: Collision teleports rectangle to corner

Post by pgimeno »

Can you provide a runnable example? Doesn't have to be your full program, just a short demo of the problem to see everything in context so we can debug.
Actravaz
Prole
Posts: 5
Joined: Sat May 21, 2022 6:16 pm

Re: Collision teleports rectangle to corner

Post by Actravaz »

Well the problem is that this IS most of my code already. i just started this project awhile ago so the only different code here is me executing functions.EDIT: i also meant to say that everything else works
User avatar
GVovkiv
Party member
Posts: 668
Joined: Fri Jan 15, 2021 7:29 am

Re: Collision teleports rectangle to corner

Post by GVovkiv »

Actravaz wrote: Sun May 22, 2022 1:46 pm Well the problem is that this IS most of my code already. i just started this project awhile ago so the only different code here is me executing functions.EDIT: i also meant to say that everything else works
So, you want us to build runnable example for you?
Actravaz
Prole
Posts: 5
Joined: Sat May 21, 2022 6:16 pm

Re: Collision teleports rectangle to corner

Post by Actravaz »

Alright alright, sheesh I guess i'll just send the file i just wanted an answer to what in my collision script caused this.
Physics.love
(1.43 KiB) Downloaded 60 times
wasd to move and you have to be actively moving to the corner without touching the sides (sorry about how hard it is).
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: Collision teleports rectangle to corner

Post by pgimeno »

It's much easier to match what's happening with what the code says when you can see it running for yourself. It's also easier to understand what the variables are and how the checks are run. And you'd be surprised by how often someone asks for help and shows a snippet of code, and the problem turns out to be elsewhere. That wasn't the case in this instance, but it's so frequent that I don't bother to even read the code in the first place without a runnable example.

In addition, having runnable code facilitates debugging, printing values and testing possible solutions.

In this case, the problem is that you have the boundary checks wrong. The corners are penetrable, and when a shape penetrates the other through a corner, it jumps as soon as it ceases to be in the corner.

You can fix it by going through each edge and checking if the old position is outside and the new is inside the other shape. Here's an example:

Code: Select all

function collide(object)
    for i,v in ipairs(workspace) do
        if CheckCollision(object.xpos,object.ypos,object.x,object.y,v.xpos,v.ypos,v.x,v.y) and v ~= object then
            if object.olypos >= v.ypos + v.y and object.ypos < v.ypos + v.y then
                object.vely = 0
                object.ypos = v.ypos + v.y
            end
            if object.olypos <= v.ypos - object.y and object.ypos > v.ypos - object.y then
                object.vely = 0
                object.ypos = v.ypos - object.y
            end

            if object.olxpos >= v.xpos + v.x and object.xpos < v.xpos + v.x then
                object.velx = 0
                object.xpos = v.xpos + v.x
            end
            if object.olxpos <= v.xpos - object.x and object.xpos > v.xpos - object.x then
                object.velx = 0
                object.xpos = v.xpos - object.x
            end
        end
    end
end
If you understand how the CheckCollision function works, you shouldn't have much problem understanding that code. I'll explain the first if; the rest are just the same but applied to the other boundaries.

The check object.olypos >= v.ypos + v.y means that the top border of the object in its previous position is below the bottom border of each object being checked. That is, the old position was not penetrating the object. Similarly, if the expression object.ypos < v.ypos + v.y is true, it means that the new position is penetrating the object. When both conditions are true, it means that this edge has intervened in the collision (which we know is happening because CheckCollision told us) and the position for this edge needs to be fixed.

Mind you, this check is not perfect. If the speed is big you can have the "bullet through wall" effect, because you're not applying swept collisions. Swept collisions are much harder to implement. But with reasonable speeds and object sizes there shouldn't be much trouble. If you have trouble with that you can always make several updates per frame. There's another potential issue, which is that one object may start inside the other. That can happen in some corner cases if you have boxes close to each other.

To prevent all those weird cases, you can use a collision library instead of trying to implement collisions yourself.
Actravaz
Prole
Posts: 5
Joined: Sat May 21, 2022 6:16 pm

Re: Collision teleports rectangle to corner

Post by Actravaz »

So your example checks if the box is both penetrating and nonpenetrating and then uses the size to return it outside? And for me only giving a snippet, I already knew that everything else worked because it was mostly spawning and instance commands and for velocity it worked fine because in a previous method I did, the box never penetrated. But yes, I can understand why you would need a demo for variables and other cases.
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: Collision teleports rectangle to corner

Post by pgimeno »

Actravaz wrote: Sun May 22, 2022 6:40 pm So your example checks if the box is both penetrating and nonpenetrating and then uses the size to return it outside?
It checks if the box WAS not penetrating each side but now it IS.

The position adjustments are the same you used, I haven't changed that. I just removed other useless code.
Actravaz
Prole
Posts: 5
Joined: Sat May 21, 2022 6:16 pm

Re: Collision teleports rectangle to corner

Post by Actravaz »

Thanks m8 this helped me a lot.
Post Reply

Who is online

Users browsing this forum: No registered users and 53 guests