javaanimationgeometryborderbounce

Bouncing Ball won't stop at borders JAVA


My bouncing ball is meant to bounce between 200x200 window's borders. I'v managed to make him stop and change direction when he touches the right and bottom borders. But when he reaches the top and left borders, a 1/4 of the ball goes through the border and only then it changes direction.

I have no idea why it happens, I mean it's literally the same code lines for each border. How can it even be that for the same code it will work differently?

I went through lots of codes around the net about this topic, and tried every solution or code, and it's still stays the same.

Thanks.

 public Point applyToPoint(Point p) {
        return new Point(p.getX() + dx, p.getY() + dy);
    }

    public void moveOneStep(int width, int height) {
    if (this.center.getX() + this.getVelocity().dx + r > width) {
        this.setVelocity(-(this.getVelocity().dx), this.getVelocity().dy);
    }
    if (this.center.getX() + this.getVelocity().dx < 0) {
        this.setVelocity(-(this.getVelocity().dx), this.getVelocity().dy);
    }
    if (this.center.getY() + this.getVelocity().dy + r > height) {
        this.setVelocity(this.getVelocity().dx, -(this.getVelocity().dy));
    }
    if (this.center.getY() + this.getVelocity().dy < 0) {
        this.setVelocity(this.getVelocity().dx, -(this.getVelocity().dy));
    }
    moveOneStep();
}

public void moveOneStep() {
    this.center = this.getVelocity().applyToPoint(this.center);
}

r = radius of the ball.

"this.center" = the center point of the ball.

screenshot of the ball on the left border:

img

 import biuoop.DrawSurface;
import biuoop.GUI;
import biuoop.Sleeper;

public class BouncingBallAnimation {

    static private void drawAnimation(Point start, double dx, double dy) {
        GUI gui = new GUI("BouncingBall",200,200);
        Sleeper sleeper = new Sleeper();
        Ball ball = new Ball(new Point(start.getX(), start.getY()), 30, java.awt.Color.BLACK);
        ball.setVelocity(dx, dy);
        while (true) {
            DrawSurface d = gui.getDrawSurface();
            ball.moveOneStep(d.getHeight(),d.getWidth());
            ball.drawOn(d);
            gui.show(d);
            sleeper.sleepFor(50);  // wait for 50 milliseconds.
        }
    }
    public static void main(String[] args) {
        drawAnimation(new Point(20,33),6,6); //just a random input that I decided
    }
}

Solution

  • Ok so here's the working code: public void moveOneStep(int startX, int height, int startY, int width) {

        if (this.center.getX() + this.getVelocity().dx + r >= width) {
            this.setVelocity(-1 * (this.getVelocity().dx), this.getVelocity().dy);
        }
        if (this.center.getX() + this.getVelocity().dx - r <= startX) {
            this.setVelocity(-1 * (this.getVelocity().dx), this.getVelocity().dy);
        }
        if (this.center.getY() + this.getVelocity().dy + r >= height) {
            this.setVelocity(this.getVelocity().dx, -1 * (this.getVelocity().dy));
        }
        if (this.center.getY() + this.getVelocity().dy - r <= startY) {
            this.setVelocity(this.getVelocity().dx, -1 * (this.getVelocity().dy));
        }
        moveOneStep();
    }
    

    The problem was not the code but the starting point I entered to check the circle. You can't give the circle a starting center point of lets say (20,50) if the Radius is 30. Why? Because then the circle will be out of bounds right from the beginning, because he has a starting center point of 20,50, and radius of 30, which means his left radius will reach (-10, 50). And that's why I had many problems. You always should check if the starting point fits the radius.