简体   繁体   English

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

[英]How to test if one rect is in another rect?

Alright, so I'm working on a game and I have found out that my enemies don't like my collision detection that works perfectly for my player. 好吧,所以我正在开发一款游戏,我发现我的敌人不喜欢我的碰撞检测,这对我的玩家来说非常有效。 After a little debugging I found out it's because my enemies are bigger than my tiles, while my player is smaller than my tiles. 经过一些调试我发现它是因为我的敌人比我的瓷砖大,而我的玩家比我的瓷砖小。

Now I need to be able to make big enemies and bosses, so this just won't do. 现在我需要能够成为大敌和老板,所以这不会做。 so I need to figure out a better way to test collision detection. 所以我需要找出一种更好的方法来测试碰撞检测。 This is how I am currently doing it: 这就是我目前的做法:

up and down: 上和下:

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
}

left and right: 左和右:

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
}

在Java中,使用intersects(Rectangle r)

Here's how to correctly do the separating axis tests (for oriented bounding boxes, like you're doing). 以下是如何正确进行分离轴测试(对于定向边界框,就像你正在做的那样)。

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

Go to this site, and play with Figure 3, making all of these true one at a time. 转到此站点,并使用图3,一次性完成所有这些。 Then break each of the tests, one at a time. 然后一次一个地打破每个测试。 You'll see empirically that it works, and is about as simple as you can get: 你会凭经验看到它有效,而且就像你能得到的一样简单:

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

If you feel like it, read through the whole set of tutorials. 如果你喜欢它,请阅读整套教程。 It'll be worth it once you start packing more features into your game :) 一旦你开始在你的游戏中包含更多功能,它将是值得的:)

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

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

bool CGRectIntersectsRect(CGRect rect1, CGRect rect2)

I think the problem lies in 我认为问题在于

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

(In first code), this will only be true if enemy is within the tile fully (height-wise) (在第一个代码中),只有当敌人在瓷砖内完全(高度方面)时才会出现这种情况

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

Like you have done with the left + right check. 就像你用左+右检查一样。

Just to clarify this would mean the first check you gave would be: 只是为了澄清这意味着你给的第一张支票将是:

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

} }

And with this I dont think you would need seperate up/down left/right checks, this should return true if ANY part of enemy is within tile 有了这个我不认为你需要单独上/下左/右检查,如果敌人的任何部分在瓦片内,这应该返回true

The sprite is wider than the tile, but the "left-right" code doesn't check for that case. 精灵比拼贴宽,但“左右”代码不检查该情况。 If i graph your code, it simply checks whether the enemy left or the enemy right lies within the tile: 如果我描绘你的代码,它只是检查敌人是否离开或敌人是否位于磁贴内:

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

but if the entire tile lies within the enemy region, no hit is detected: 但如果整个瓷砖位于敌方区域内,则未检测到任何击中:

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

Similarly, the Tile is smaller vertially than the enemy, so it is necessary to check the if the entire tile lies within the enemy. 同样,Tile比敌人更小,因此有必要检查整个瓷砖是否位于敌人之内。 The complete graph/pseudo code is: 完整的图形/伪代码是:

 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
 ]

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM