0
\$\begingroup\$

My Breakout game works fine so far, but I struggle with the collision detection... Well... just with the collision from the ball with the brick... Here's the relevant code:

List<Brick> removeList = new ArrayList<>();
for (Brick b : bricks) {
    if (ball.intersects(b)) {
        float x = b.getX();
        float y = b.getY();
        float width = b.getWidth();
        float height = b.getHeigth();

        Line2D.Float left = new Line2D.Float(x, y, x, y + height);
        Line2D.Float right = new Line2D.Float(x + width, y, x + width, y + height);
        Line2D.Float top = new Line2D.Float(x, y, x + width, y);
        Line2D.Float bottom = new Line2D.Float(x, y + height, x + width, y + height);
        Rectangle2D bounds = ball.getShape().getBounds2D();

        if (bounds.intersectsLine(left)) {
            ball.setVelocityX(-ball.getVelocityX());
            ball.setX(b.getX() - ball.getWidth());
        } else if (bounds.intersectsLine(right)) {
            ball.setVelocityX(-ball.getVelocityX());
            ball.setX(b.getX() + b.getWidth());
        } else if (bounds.intersectsLine(top)) {
            ball.setVelocityY(-ball.getVelocityY());
            ball.setY(b.getY() - ball.getHeigth());
        } else if (bounds.intersectsLine(bottom)) {
            ball.setVelocityY(-ball.getVelocityY());
            ball.setY(b.getY() + b.getHeigth());
        }
        removeList.add(b);
    }
}
bricks.removeAll(removeList);
objects.removeAll(removeList);

I thought it would work like this, but sometimes the ball does the wrong collision e.g. when the ball comes from down and it hits the brick near the edge it would collide like it hit from the left!

Is something wrong with my code? Maybe it is the wrong approach?

EDIT
Like you can see in the code above I'll get the borders left, right, top and bottom from the x and y coordinates.
After that I check which border was intersected by the ball and determine from which side the brick was hit.

\$\endgroup\$

closed as off-topic by Anko, MichaelHouse Feb 24 '14 at 15:41

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about debugging a problem in your project must present a concise selection of code and context so as to allow a reader to diagnose the issue without needing to read all of your code or to engage in extensive back-and-forth dialog. For more information, see this meta thread." – MichaelHouse
If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ I strongly suggest you try learning box2d instead of spending your time learning how to implement collisions correctly. \$\endgroup\$ – wolfdawn Feb 24 '14 at 10:39
  • 1
    \$\begingroup\$ Why should I learn a pyhsic engine when I want to do that by myself? \$\endgroup\$ – user42605 Feb 24 '14 at 11:21
  • \$\begingroup\$ @Arthur For simple physics and collision detection, Box2D is overkill. Even using Box2D, writing some collision tests yourself is educational and will help when debugging. \$\endgroup\$ – Anko Feb 24 '14 at 13:16
  • \$\begingroup\$ Could you describe what your approach is rather than what your code is? Often the problem with collision detection isn't with the code you've written, but the way you're thinking about it. \$\endgroup\$ – Anko Feb 24 '14 at 13:18
  • 1
    \$\begingroup\$ @Arthur Ah yes, only flipping the velocity would give occasional frames where the ball is inside a block; it wouldn't be collision detection so much as... just collision. I agree with that. (Sorry for all the confusion; everyone's comments are split between the answers and question. I think this is what is meant by discussion questions not fitting the SE format.) \$\endgroup\$ – Anko Feb 25 '14 at 9:30
1
\$\begingroup\$

I see your code uses else if for all the intersection checks. If the ball moves at a decent speed, it is very likely that it will collide with several lines (for example, left and top), but your code will only allow it to collide with one side at the time, resulting in erronous velocities from time to time.

Note that errors can still happen even if you remove the else before the if, if your ball moves fast enough, so that it can move "through" a brick from loop cycle to loop cycle. To fix that, you will have to "look ahead" in time to determine the time a collision would occur.

\$\endgroup\$
  • \$\begingroup\$ Still strange collisions if it hits one of the edges :( \$\endgroup\$ – user42605 Feb 24 '14 at 13:33
  • \$\begingroup\$ I think this correctly identifies the problem, but I think @user42605 could use more details. Can you elaborate to offer better explanation? \$\endgroup\$ – Seth Battin Feb 24 '14 at 15:29
  • \$\begingroup\$ No if I remove the elses then the ball can collide with more than one site and that is something I don't want. The wrong collision only happens near the edges of the Block. \$\endgroup\$ – user42605 Feb 24 '14 at 15:35
  • \$\begingroup\$ @user42605 You are assuming that the ball's movement is "perfect", in that you have pixel-perfect control of where it is. Most likely, you will not have this, but it will move several pixels pr. loop cycle. If it comes down from the top (on the left-ish side of the brick), it will logically cross the top-line first, but if close enough to the corner, it will cross the left line too. Since the left check is first, - it will look like it came from the left in your hit checks. \$\endgroup\$ – Terje Feb 24 '14 at 19:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.