开发者

Box Collision code

开发者 https://www.devze.com 2023-03-07 18:08 出处:网络
My box collision code is not working. bool checkCollide(int x, int y, int oWidth, int oHeight, int xTwo, int yTwo, int oTwoWidth, int oTwoHeight)

My box collision code is not working.

bool checkCollide(int x, int y, int oWidth, int oHeight, int xTwo, int yTwo, int oTwoWidth, int oTwoHeight)
{
   if (xTwo + oTwoW开发者_如何学运维idth < x) 
      return false;  // box 2 is left of box 1

   if (x + oWidth < xTwo)
      return false;  // box 1 is left of box 2

   if (xTwo > x + oWidth) 
      return false;  // box 2 is right of box 1

   if (x > xTwo + oTwoWidth)
      return false;  // box 1 is right of box 2


   if (yTwo + oTwoHeight < y) 
      return false;  // box 2 is up of box 1

   if (y + oHeight < yTwo)
      return false;  // box 1 is up of box 2

   if (yTwo > y + oHeight) 
      return false;  // box 2 is down of box 1

   if (y > yTwo + oTwoHeight)
      return false;  // box 1 is down of box 2

   return true;
}

On of my boxes is clearly going over the other, however nothing is happening. It seems to be returning false for some reason. I'm checking if one "rectangle" is out of bounds of the other, and if it isn't return true. Why isn't it working?


Here is how I would have done it (I would have provided an AABB object instead trough)

bool checkCollide(int x, int y, int oWidth, int oHeight, int xTwo, int yTwo, int oTwoWidth, int oTwoHeight)
{
    // AABB 1
    int x1Min = x;
    int x1Max = x+oWidth;
    int y1Max = y+oHeight;
    int y1Min = y;

    // AABB 2
    int x2Min = xTwo;
    int x2Max = xTwo+oTwoWidth;
    int y2Max = yTwo+oTwoHeight;
    int y2Min = yTwo;

    // Collision tests
    if( x1Max < x2Min || x1Min > x2Max ) return false;
    if( y1Max < y2Min || y1Min > y2Max ) return false;

    return true;
}

Indeed you can replace the x1Max etc directly with the values instead of using temporary variables. I added them for readability.

bool checkCollide(int x, int y, int oWidth, int oHeight, int xTwo, int yTwo, int oTwoWidth, int oTwoHeight)
{
    if( x+oWidth < xTwo || x > xTwo+oTwoWidth ) return false;
    if( y+oHeight < yTwo || y > yTwo+oTwoHeight ) return false;

    return true;
}

Note that this function does work with 2D boxes only, but it only require one more test line with z axis to be 3D compatible.

----------

Now let see your code with some comments on it

bool checkCollide(int x, int y, int oWidth, int oHeight, int xTwo, int yTwo, int oTwoWidth, int oTwoHeight)
{
   if (xTwo + oTwoWidth < x)    //(1) if( x2Max < x1Min )
      return false;

   if (x + oWidth < xTwo)       //(2) if( x1Max < x2Min )
      return false;

   if (xTwo > x + oWidth)       //(3) if( x2Min > x1Max ) ==> if( x1Max < x2Min ) ==> (2)
      return false;

   if (x > xTwo + oTwoWidth)    //(4) if( x1Min > x2Max ) ==> if( x2Max < x1Min ) ==> (1)
      return false; 


   if (yTwo + oTwoHeight < y)   //(5) if( y2Max < y1Min )
      return false;

   if (y + oHeight < yTwo)      //(6) if( y1Max < y2Min )
      return false;

   if (yTwo > y + oHeight)      //(7) if( y2Min > y1Max ) ==> if( y1Max < y2Min ) ==> (6)
      return false;

   if (y > yTwo + oTwoHeight)   //(8) if( y1Min > y2Max ) ==> if( y2Max < y1Min ) ==> (5)
      return false;

   return true;
}

So as you can see, half the tests are not required. Considering the X axis, you first test is the same as the fourth one; your second test is the same as the third one.

----------

However, I can't spot any reason why your function does not return true when the box are overlapping. It should work.

I tested with the following values

std::cout << checkCollide(5, 5, 2, 2, 0, 0, 3, 3) << std::endl; // false no collision
std::cout << checkCollide(5, 5, 2, 2, 4, 4, 3, 3) << std::endl; // true collision

And it return false, and true as expected.


bool checkCollide(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
  if (y1 + h1 < y2
     || y1 > y2 + h2
     || x1 + w1 < x2
     || x1 > x2 + w2) return false;
  return true;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消