0
votes

I am having trouble with testing if a rectangle has collided with another rectangle and where the collision is in relation to each object (Left, right, Top, Bottom).

My code works well in theory but there are logical issues, there are false positives when an object enters the left side of another object. The parameters I have set mean that both the top collision and left collision become true when in truth only the left should be true.

image of problem

How can I stop a double positive happening in my code, I only need basic rectangle collision and nothing more. Thank you.

//Col on top?
if (Obj1.getRect(this).bottom - vSpeed < Obj2.getRect(this).bottom && 
    Obj1.getRect(this).bottom - vSpeed > Obj2.getRect(this).top)
{           
    if (Obj1.getRect(this).right + hSpeed > Obj2.getRect(this).left &&
        Obj1.getRect(this).left + hSpeed < Obj2.getRect(this).right)
    {

        Obj1.y = Obj2.y - Obj1.height;
        vSpeed = 0;

        colTop = true;

    }
}
    //Col on Bottom?
else if (Obj1.getRect(this).top - vSpeed > Obj2.getRect(this).top && 
         Obj1.getRect(this).top - vSpeed < Obj2.getRect(this).bottom)
{       
    if (Obj1.getRect(this).right + hSpeed > Obj2.getRect(this).left &&
        Obj1.getRect(this).left + hSpeed < Obj2.getRect(this).right)
    {

        Obj1.y = Obj2.y + Obj2.height;
        vSpeed = 0;

        colBot = true;

    }           
}

//Col on left side?
if (Obj1.getRect(this).right + hSpeed > Obj2.getRect(this).left &&
    Obj1.getRect(this).right + hSpeed < Obj2.getRect(this).right)
{       
    if (Obj1.getRect(this).bottom - vSpeed > Obj2.getRect(this).top && 
        Obj1.getRect(this).top - vSpeed < Obj2.getRect(this).bottom)
    {

        Obj1.x = Obj2.x - (Obj2.width * 0.5);
        hSpeed = 0;

        colLeft = true;

    }
}
    //Col on right side?
else if (Obj1.getRect(this).left + hSpeed > Obj2.getRect(this).left &&
         Obj1.getRect(this).left + hSpeed < Obj2.getRect(this).right)
{       
    if (Obj1.getRect(this).bottom - vSpeed > Obj2.getRect(this).top && 
        Obj1.getRect(this).top - vSpeed < Obj2.getRect(this).bottom)
    {

        Obj1.x = (Obj2.x + Obj2.width) + (Obj1.width * 0.5);
        hSpeed = 0;

        colRight = true;

    }
}
2
Not sure what you meant, do you mean I should remove the final alterations to Obj1's co-ords and velocity alterations out of my if statements? That would result in the same problem, it would see Top is true when the player is moving into the left side of Obj2 and move Obj1 to the top. If I got the just of what you were saying.user3307694

2 Answers

0
votes

You need to separate top collision from left collision by parsing the objects' relative speed. You cannot parse top/left collision using coordinates only because they are really both true if one rectangle's top left point goes inside another rectangle. So, move your Obj1 and velocity altering code out of your array of if statements, and leave the rest of the code as is. Then you check for velocities like this:

if (colTop) 
    if (Obj1.getRect(this).bottom > Obj2.getRect(this).top)
        colTop=false;

Etc., for other collision vars. This code means: "If the bottom of Obj1 already was under the top of Obj2, then in this frame we are not hitting the top side". So, only the left side collision flag should remain. And only then you check for resultant collision vars and adjust coordinates and velocities

0
votes

The starling library provides great collision detection, including simple rectangle collision. Are your methods being called on every frame? All you would need for Starling collision detection is:

var bounds1:Rectangle = image1.bounds;
var bounds2:Rectangle = image2.bounds;

if (bounds1.intersects(bounds2))
   trace("Collision!");

collision detection