c++ - 盒碰撞码

扫码查看

我的盒子碰撞代码无法正常工作。

bool checkCollide(int x, int y, int oWidth, int oHeight, int xTwo, int yTwo, int oTwoWidth, int oTwoHeight)
{
   if (xTwo + oTwoWidth < 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;
}


我的盒子上显然要经过另一个盒子,但是什么也没发生。
由于某种原因,它似乎返回false。我正在检查一个“矩形”是否超出另一个矩形的边界,以及是否未返回true。为什么不起作用?

最佳答案

这是我的操作方式(我会提供AABB对象而不是槽)

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;
}


实际上,您可以直接用值替换x1Max等,而不是使用临时变量。我添加它们是为了提高可读性。

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;
}


请注意,此功能仅适用于2D盒,但仅需再一条带有z轴的测试线即可与3D兼容。

----------

现在,让我们看一下带有一些注释的代码

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;
}


如您所见,不需要一半的测试。
考虑到X轴,您的第一个测试与第四个相同。您的第二项测试与第三项相同。

----------

但是,当框重叠时,我无法发现您的函数为何不返回true的任何原因。它应该工作。

我测试了以下值

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


并且它返回false和true符合预期。

关于c++ - 盒碰撞码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6083626/

10-11 22:50
查看更多