• Advertisement
Sign in to follow this  

Two rectangles colliding

This topic is 1953 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

There is a tutorial here that explain how to check if two 2D-rectangles collide. It works excellent in most cases in my game.
There is an other case where I need to check if the unit is colliding from the right, left, up or down. I am having trouble getting this function to work.

Anyone have or know a piece of code that works(C/C++/Java/C#)?

Share this post


Link to post
Share on other sites
Advertisement
I use to solve this by having a "direction" of the objects. If you have for example an enemy object then you can use
if(x1.intersects(x2)){

if(enemy.dx == 1)
- do something
if(enemy.dx == -1)
- do something
if(enemy.dy == 1)
- do something
if(enemy.dy == -1)
- do something

Maybe that's a bad method, but I use it :)

Share this post


Link to post
Share on other sites
You can use Dot Product for this purpose.

Consider PlayerDir as a vector pointing in direction the player looks and EnemyDir is the direction in which an enemy moves.

Using following calculation :

(PlayerDir.x * EnemyDir.x + PlayerDir.y * EnemyDir.y);



you get the value of cosine between their directions. Importantly, make sure that PlayerDir and EnemyDir are normalized! Otherwise you have to divide your result by length of both vectors!

If result was positive it means, that player and enemy moved in the same direction, so the player was hit in the back. If negative than, they moved in opposite directions. If you get value really close to 0, it means the player was hit from the side. Edited by DgekGD

Share this post


Link to post
Share on other sites
I've implemented a simple collision detection/response method for a 2d platform game project. At the moment, the only response I've coded is between player and platform collisions.

Collision util functions are defined here:
https://github.com/larsbutler/gamedemo/blob/master/src/com/larsbutler/gamedemo/math/Collision.java

And everything is used here:
https://github.com/larsbutler/gamedemo/blob/master/src/com/larsbutler/gamedemo/core/GameState.java#L95

This method would need to be optimized for lots of collisions, but for a low number it works well; it's reliable and stable.

I hope that helps.

Share this post


Link to post
Share on other sites
We have rectangles R1 and R2. R1 has middle point (x1,y1), height h1, width w1, and is moving at velocity (vx1, vy1). Same stuff for R2.

Now let's assume we know there's a sideways collision between rectangles R1 and R2. It's really easy to determine which side the collision is on: you just look at their relative velocities. If vx2-vx1>0, R2 hit R1 from the left, otherwise it hit R1 from the right. If we know we have a vertical collision, same thing, we check vy2-vy1>0.

Looking at the middle points, x2-x1>0, would also work if the rectangles move slowly relative to their size. If they move so fast that one rectangle is already more than halfway inside the other when the collision check happens, this will produce a collision from the wrong side whereas velocities would produce the right result. Of course, if the rectangles move even faster, they will get past each other entirely before the collision check happens. To prevent that you'd have use a different strategy to check for collisions in the first place.

So that was trivial. The more interesting part is determining whether your collision is sideways or vertical. This is how I'd go about checking it:
1) For a collision to have happened, the rectangles must now be overlapping in both x and y directions.
2) We assume this is the first frame when the collision happens.
3) Therefore, on the last frame, the collision was not happening, and that means either the rectangles were overlapping in x direction, overlapping in y direction, or neither.
4) The last direction of those two directions which came to overlap is the collision direction.
(how to check presence of overlap between two rectangles in x-direction: abs(x1-x2) < (w1+w2)/2)
5) We check overlap between oldR1 and oldR2.
(we can get the old coordinates from new coordinates and velocity; oldx1 = x1-vx1, oldy1 = y1-vy1 and so on).
6) If there was x overlap between oldR1 and oldR2, the collision is vertical, because it's impossible for two rectangles overlapping in x direction to move in a straight line and collide horizontally. If there was y overlap between oldR1 and oldR2, the collision is horizontal.
7) In the special case that there was no x-overlap and no y-overlap, both overlaps occurred between last frame and this frame. Now it is slightly harder to figure out which of those overlaps occurred first and which occurred last. We'll call the moment of time when x overlap happened as timex and its counterpart as timey. With the exact same logic as before, if timex < timey is true, the collision is vertical, otherwise it is horizontal.
8) How to get timex and timey? It's elementary physics; distance divided by velocity equals time. In this case, the distance is the gap between the rectangles, and the velocity is the rectangles' relative velocity.
(timex = gapx / vx = (abs(oldx2-oldx1)-(w1+w2)/2) / abs(vx2-vx1)) Edited by Stroppy Katamari

Share this post


Link to post
Share on other sites

I have resolved this problem.
It would be considerate to tell how you resolved your problem, both for the benefit of those who have the same problem later, and for the benefit of those who tried to give you advice.

Share this post


Link to post
Share on other sites
Funny you should mention this, I just finished posting a two part tutorial on bounding box collisions.

Part One -- covers the concept of an AABB in the first place, as well as having the code to check for a rectangle on rectangle collision.
Part Two -- which I literally posted 15 minutes ago, covers resizing the bounding box as your sprite rotates.

Both samples have a running example in the browser ( JavaScript using Easel ), but break out the math specific parts into their own section and have a complete explanation how everything works. Although the samples are in JavaScript, the code is basically 90% compatible with C#/C++/Java, so you only need to change a few key words to get it to compile in your language of choice ( which is why I went with JavaScript for examples... that and obviously it runs in the browser ).

Share this post


Link to post
Share on other sites
My solution is irrelevant because uses variables that are exclusive to my game(and not to an actual rectangle) to calculate this. Edited by P0jahn

Share this post


Link to post
Share on other sites
Well my so called "solution" was limited to work with one single situation and the code is not reusable.
I want a global method to check this, so I have looked a bit closer at Stroppy Katamaris post.
With all due respect, your text is cryptic. Why is velocity needed? Old R2? timex/timey?
Could you please clarify your post?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement