3

I'm trying to make an arkanoid-like game, and now I'm facing a problem with the collisions. As usual, the bricks are rectangles (in my case, squares) and the ball is a circle, so it's all about axis aligned bounding boxes.

So far, I've got the trivial collision detection algorithm, but I need to know what side of each brick the ball hits. For example: Collision cases

So far I have an algorithm that checks whether each side has been hit:

up = left = right = down = 0;

if(mouse.left < brick.left && brick.left < mouse.right && mouse.right < brick.right){   
    left = 1;
}

if(brick.left < mouse.left && mouse.left < brick.right && brick.right < mouse.right){
    right = 1;
}

if(mouse.top < brick.top && brick.top < mouse.bottom && mouse.bottom < brick.bottom){
    up = 1;
}

if(brick .top < mouse.top && mouse.top < brick.bottom && brick.bottom < mouse.bottom){
    down = 1;
}

But in the collisions close to the corners, like the third in the image, two flags (for instance, left and down) are set to 1, so I don't know how to decide.

What is usually done in these cases?

José Tomás Tocino
  • 9,873
  • 5
  • 44
  • 78
  • Reverse trajection? This is literally and "edge-case". You need to decide what to do here. No really: Do what you feel is appropriate. – Sani Huttunen Feb 05 '11 at 00:46
  • Why do you need to know which edge? If you're trying to do proper reflection of the ball you should be doing something else, like point/capsule collision vs. all 4 edges. – Tetrad Feb 05 '11 at 00:47

1 Answers1

2

Don't just set it to one, set it to the penetration depth:

// why is it named mouse?
if(mouse.left < brick.left && brick.left < mouse.right &&
    mouse.right < brick.right)
{
    left = mouse.right - brick.left;
}

// and so on...

Then when you're done, you can pick whichever is minimum to be your main side.


By the way, I don't think you want that third conditional. Imagine a case like this:

   +-+
   |B|
+--| |--+
|M | |  |
|  | |  |
+--| |--+
   +-+

Here, you have no left or right collision.

(You may also want to review the remaining conditionals for correctness.)

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • Slightly off-topic, did you write that SAT tut in Python on GPWiki? – Skurmedel Feb 05 '11 at 00:46
  • I think you'll want the minimum, not the maximum. At the corners, the side off of which you want to reflect the ball is penetrated less deeply than the other side. – joriki Feb 05 '11 at 00:47
  • BTW, if the ball is always smaller than the bricks, your collision checks are slightly redundant -- in each case, one of the 1st and the 3rd condition implies the other. – joriki Feb 05 '11 at 00:48
  • @Skurmedel: Ha, wow I forgot about that. Yeah, I did that. @joriki: Yeah, just added a commented on that. – GManNickG Feb 05 '11 at 00:50
  • The idea of measuring the penetration depth is great, now it's working very well. The second case you mention is not possible, as all the blocks are bigger than the ball. – José Tomás Tocino Feb 05 '11 at 01:12
  • @The: As a general algorithm, though, it's unnecessary *and may* break other detections. You won't lose a thing by removing it, and gain functionality. Glad the idea works for you. – GManNickG Feb 05 '11 at 01:23
  • @GMan: It's good tutorial :) My Löve implementation is still broken though but that is probably because I can't debug it properly. – Skurmedel Feb 05 '11 at 10:42
  • @Skurmedel: Thanks. :) Shame that I never finished writing the series, just got too busy with other stuff. – GManNickG Feb 05 '11 at 22:19