如何测试一个矩形是否在另一个矩形中?

时间:2010-11-08 01:21:00

标签: c# java c++ collision-detection

好吧,所以我正在开发一款游戏,我发现我的敌人不喜欢我的碰撞检测,这对我的玩家来说非常有效。经过一些调试我发现它是因为我的敌人比我的瓷砖大,而我的玩家比我的瓷砖小。

现在我需要能够成为大敌和老板,所以这不会做。所以我需要找出一种更好的方法来测试碰撞检测。这就是我目前正在做的事情:

上下:

if((enemy.left > tile.left && enemy.left < tile.right || enemy.right > tile.left && enemy.right < tile.right) && enemy.top < tile.bottom && enemy.bottom > tile.top){
    //collision
}

左右:

if((enemy.top > tile.top && enemy.top < tile.bottom || enemy.bottom > tile.top && enemy.bottom < tile.bottom) && enemy.left < tile.right && enemy.right > tile.left){
     //colision
}

7 个答案:

答案 0 :(得分:5)

在Java中,使用intersects(Rectangle r)

答案 1 :(得分:3)

以下是如何正确进行分离轴测试(对于定向边界框,就像你正在做的那样)。

if (firstObject.Left < secondObject.Right && firstObject.Right > secondObject.Left
    && firstObject.Top < secondObject.Bottom && firstObject.Bottom > secondObject.Top)
{
    // Intersecting
}

转到此站点,并使用图3,一次性完成所有这些。然后一次一个地打破每个测试。你会从经验上看出它是有效的,并且就像你能得到的一样简单:

http://www.metanetsoftware.com/technique/tutorialA.html#section1

如果您愿意,请仔细阅读整套教程。一旦你开始在你的游戏中包含更多功能,这将是值得的:)

答案 2 :(得分:2)

在.NET语言中,您可以使用Rectangle.IntersectsWith(Rectangle other)方法执行非常基本的碰撞检测。

答案 3 :(得分:2)

对于在Objective-C中工作的人,您可以使用相同的答案:

bool CGRectIntersectsRect(CGRect rect1, CGRect rect2)

答案 4 :(得分:1)

我认为问题在于

enemy.top < tile.bottom && enemy.bottom > tile.top

(在第一个代码中),只有当敌人完全在(在高度范围内)时,这才会成立

enemy.top > tile.top && enemy.top < tile.bottom || enemy.bottom > tile.top && enemy.bottom < tile.bottom

就像你用左+右检查一样。

只是为了澄清这意味着你给的第一张支票是:

if((enemy.left > tile.left && enemy.left < tile.right || enemy.right > tile.left && enemy.right < tile.right) && (enemy.top > tile.top && enemy.top < tile.bottom || enemy.bottom > tile.top && enemy.bottom < tile.bottom)){
//collision

}

有了这个我不认为你需要单独上/下左/右检查,如果敌人的任何部分在瓦片内,这应该返回

答案 5 :(得分:0)

精灵比瓷砖宽,但“左右”代码不检查这种情况。 如果我描绘你的代码,它只是检查敌人是否离开或敌人是否位于该区块内:

(enemy.left > tile.left && enemy.left < tile.right
|| enemy.right > tile.left && enemy.right < tile.right)

// graphed as<br>
// TL EL TR ----- or ----- TL ER TR<br>

但如果整个瓷砖位于敌方区域内,则未检测到任何命中:

//  EL TL ----- and ----- TR ER

同样地,Tile比敌人更小,所以有必要检查整个瓷砖是否位于敌人之内。 完整的图/伪代码是:

 is_hit :
 // T{L,R,T,B} => tile, E{L,R,T,B} => enemy
 // left-right:
 [
  TL EL TR ----- or ----- TL ER TR
           . or .
  EL TL ----- and ----- TR ER
 ]
 .and.
 // top-bottom:
 [
  TT ET TB ----- or ----- TT EB TB
           . or .
  ET TT ----- and ----- TB EB
 ]

答案 6 :(得分:0)

.Net中,Intersect(Rect rect)类中已有一个名为Rect的方法。