1
\$\begingroup\$

I am making a platformer game, my way of handling collision works most of the times, but when I jump on a platform's corner I get pushed away, it probably happens because my function returns right or left respectively and not bottom collision. Is there anyway to modify this function to work, or is there another algorithm that works better?

public static string RectangleCollision(Rectangle r1, Rectangle r2) {
    string result;

    float w = 0.5f * (r1.Width + r2.Width);
    float h = 0.5f * (r1.Height + r2.Height);
    float dx = r1.Center.X - r2.Center.X;
    float dy = r1.Center.Y - r2.Center.Y;

    if (Math.Abs(dx) <= w && Math.Abs(dy) <= h) {

        // Collision
        float wy = w * dy;
        float hx = h * dx;

        if (wy > hx) {
            if (wy > -hx) {
                // Collision on top
                result = "top";
            } else {
                // On left
                result = "left";
            }
        } else {
            if (wy > -hx) {
                // on right
                result = "right";
            } else {
                // on bottom
                result = "bottom";
            }
        }

     } else {
         result = "false";
     }

     return result;
}
```
\$\endgroup\$
0
\$\begingroup\$

Can you provide some screenshots of the problem?

Just try this method below, I hope it can solve your problem:

        public HitState checkHit(Rectangle r1, Rectangle r2)
        {
           HitState retv;
            retv.hit = false;
            retv.hitTop = false;
            retv.hitBottom = false;
            retv.hitLeft = false;
            retv.hitRight = false;
            retv.hitInside = false;
            retv.hitExact = false;

            Rectangle temp1 = Rectangle.Intersect(r1, r2);
            if (temp1.Width == 0 && temp1.Height == 0)
            {
                return retv;
            }

            retv.hit = true;
            if (temp1.Y == r1.Y) retv.hitTop = true;
            if (temp1.Y+temp1.Height == r1.Y+r1.Height) retv.hitBottom = true;
            if (temp1.X == r1.X) retv.hitLeft = true;
            if (temp1.X+temp1.Width == r1.X+r1.Width) retv.hitRight = true;

            return retv;
        }
    }

    public struct HitState
    {
        public bool hit; // true if hit
        public bool hitTop; // true if hit top
        public bool hitBottom; // true if hit bottom 
        public bool hitLeft; // true if hit left
        public bool hitRight; // true if hit right
        public bool hitInside; // true if one inside other
        public bool hitExact; // only true if both bounding boxes exact size
    }
\$\endgroup\$
  • \$\begingroup\$ Thanks for your help, unfortunately I forgot that I have posted a question here, I think your option should work, but for now I did found another way out. \$\endgroup\$ – Michael May 16 '19 at 10:41
  • \$\begingroup\$ Edit: I tried your code and it is much better, thank you a lot \$\endgroup\$ – Michael May 16 '19 at 11:23
  • \$\begingroup\$ Thanks. But this check method will return top left, top right, bottom left, bottom right. If you don't want them, just modify to meet your needs. \$\endgroup\$ – Silver May 26 '19 at 2:39
  • \$\begingroup\$ I modified it a bit for my needs and it's perfect \$\endgroup\$ – Michael May 26 '19 at 7:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.