Page 1 of 1

Collision teleports rectangle to corner

Posted: Sat May 21, 2022 6:49 pm
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

Re: Collision teleports rectangle to corner

Posted: Sat May 21, 2022 9:41 pm
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.

Re: Collision teleports rectangle to corner

Posted: Sun May 22, 2022 1:46 pm
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

Re: Collision teleports rectangle to corner

Posted: Sun May 22, 2022 1:56 pm
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?

Re: Collision teleports rectangle to corner

Posted: Sun May 22, 2022 2:46 pm
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 84 times
wasd to move and you have to be actively moving to the corner without touching the sides (sorry about how hard it is).

Re: Collision teleports rectangle to corner

Posted: Sun May 22, 2022 5:39 pm
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.

Re: Collision teleports rectangle to corner

Posted: Sun May 22, 2022 6:40 pm
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.

Re: Collision teleports rectangle to corner

Posted: Sun May 22, 2022 6:59 pm
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.

Re: Collision teleports rectangle to corner

Posted: Sun May 22, 2022 8:01 pm
by Actravaz
Thanks m8 this helped me a lot.