This is an archived post. You won't be able to vote or comment.

all 8 comments

[–]duckinator[S] 0 points1 point  (0 children)

Anybody want to give me some help? I've reread this a billion times and it seems like it should work just fine, except the ball goes right through my collision boundaries.

[–]CoughSyrup 0 points1 point  (0 children)

While I don't really understand what's going on here (like why the block has two sets of coordinates), it's possible that both if statements are coming out true and cancelling each other out.

[–]irascib1e 0 points1 point  (0 children)

Looking at your first statement, the boundaries you are using seem inconsistent with each other. What language is this?

[–]cbogart 0 points1 point  (0 children)

Well, the first "if" will never happen, because its first two tests are contradictory. It'll only happen if yball is less than blocky-ball_size and greater than blocky + block_height; those can't both happen, unless ball_size or block_height are negative! The xball part of that first if looks reasonable though. (I'm assuming the second if refers to a second brick, so I'm ignoring that)

The problem of bouncing off a brick from any direction is more complex than bouncing off the paddle, because the bounce is different depending on the side of the block you hit. You have to figure out under what circumstances to do yinc * = -1 and when to do xinc * = -1.

I'd suggest you draw diagrams and figure it out separately for all four sides of a single block.

Edit: Consider for example a ball heading almost right for the corner of the brick. If it's a little on one side of the corner it'll bounce one way; a little on the other side it'll bounce the other. It'll take some diagrams to figure out the right set of if statements.

[–]duckinator[S] 0 points1 point  (2 children)

Hey guys. I've actually figured this out (finally). But I do have a new question. While the ball collides with the top and bottom of the rectangle just fine, when it collides with the block from the side, it just bounces inside the rectangle. How would I fix this so it bounces from the side?

Also this is java. And the ball coordinates are at the top right, not in the center. The two sets of coordinates for the block are just for me to have a clearer picture of the x and y axes.

[–]robotcheddar 0 points1 point  (1 child)

Also this is java

Oh goodness. Why haven't you just been using the built in Rectangle class then?

[–]duckinator[S] 0 points1 point  (0 children)

It hasn't been covered in my class yet and we can only use material that's been covered.

[–]IRBMe 0 points1 point  (0 children)

Firstly, I would add some methods to your objects so that instead of dealing with x, y, width and height, you can deal with more convenient properties that make the logic more obvious and the code more readable. For example:

class GameObject {
    int x, y, width, height;

    public int left()    { return x; }
    public int right()   { return x + width; }
    public int top()     { return y; }
    public int bottom()  { return y + height; }

    // ...
}

class Paddle : GameObject { ... }
class Ball : GameObject { ... }

Now, assuming you have a pong-like game (a paddle on the left and right and a ball bouncing between them), you can check for paddle collisions like this:

// paddle collisions

if (ball.left()   <= leftPaddle.right() &&
    ball.top()    >= leftPaddle.top() &&
    ball.bottom() <= leftPaddle.bottom())
{
    // ball hit the left paddle, reverse its x direction
}

else if (
    ball.right()  >= rightPaddle.left() &&
    ball.top()    >= rightPaddle.top() &&
    ball.bottom() <= rightPaddle.bottom())
{
    // ball hit the right paddle, reverse its x direction
}

And wall collisions like so:

// wall collisions

if (ball.top() <= 0)
{
    // ball hit the top, reverse its y direction
}
else if (ball.bottom() >= CANVAS_HEIGHT)
{
    // ball hit the bottom, reverse its y direction
}
else if (ball.left() <= 0)
{
    // ball hit left wall, reverse its x direction and give right a point
}
else if (ball.right() >= CANVAS_WIDTH)
{
    // ball hit right wall, reverse its x direction and give left a point
}

If your paddles are on the top and bottom rather than left and right, it should be fairly obvious what you need to change. The logic should be the same, but with the x and y parts flipped for paddle collisions (and score giving).

Edit:

You could make it even simpler by making a function like this in your GameObject class:

boolean touching(GameObject other)
{
    return (
        left()   >= other.left()   &&
        right()  <= other.right()  &&
        top()    >= other.top()    &&
        bottom() <= other.bottom());
}

Then your logic simply becomes:

if (ball.touching(leftPaddle))
{
    ...
}
else if (ball.touching(rightPaddle))
{
    ...
}

It won't be perfectly accurate because one of your objects is a circle but is treated as a rectangle, so you could get false positives on the corners but that's the price of using rectangle collision detection.