2010-11-08 60 views
3

好的,所以我正在制作一款游戏,并且我发现我的敌人不喜欢我的碰撞检测功能,这对我的玩家来说非常合适。经过一些调试,我发现这是因为我的敌人比我的瓷砖大,而我的玩家比我的瓷砖小。如何测试一个矩形是否在另一个矩形中?

现在我需要能够做出大敌和老板,所以这是不行的。所以我需要找出更好的方法来测试碰撞检测。这是我当前如何做它:

上下:

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 
} 
+0

你的精灵是纯粹的矩形吗? – xandy 2010-11-08 01:27:26

+0

它是52x32,拼图是50x50 – William 2010-11-08 01:28:56

+2

我的意思是,对于大多数游戏来说,精灵的碰撞检测不是简单地检测重叠的矩形,例如,如果你的敌人和你的化身都是圆形的,即使矩形重叠也不会基本崩溃。 – xandy 2010-11-08 01:39:18

回答

5

在Java中,使用intersects(Rectangle r)

+2

+1,因为这是我选择的选项。如果我必须编写自己的自定义代码,无论如何,我都会让我的公共界面看起来像这样。 – 2010-11-08 02:11:14

2

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

+0

哦,谢谢,但我有点想到答案会更多......便携。尽管如此,当我在C#和C++和Java中编写代码时,我发现你的答案足够有用,但它不是我想要的。 编辑:在Java中的非便携式答案是好的,但是,因为这就是我的游戏编码。 – William 2010-11-08 01:36:56

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 

}

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

+0

你真的只需要大约一半的测试你在做最后的答案。检查我的答案以获得更有效的一组测试。 – 2010-11-08 02:05:13

+0

哦,是的,这是一个更好的方法。 – akd5446 2010-11-08 02:08:09

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 

类似地,瓦片比敌人更小,所以有必要检查整个瓦片是否位于敌人内部。 总图/伪代码是:

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 
] 
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

如果你喜欢它的感觉,通读整个系列教程。

bool CGRectIntersectsRect(CGRect rect1, CGRect rect2) 
2

对于任何人在Objective-C的工作寻找相同的答案,你可以使用这将是值得的在Rect类中名为Intersect(Rect rect)的方法。

0

.Net已经有一个:一旦你开始打包更多的功能集成到您的游戏:)

相关问题