Boolean flag not readable during loop (java)

I wrote a program to bounce a ball around the screen. The program, as described below, does not work (the ball just leaves the screen).

However, if I declare the boolean variables atHorizontalEdge and atVerticalEdge inside the while loop, this works. Why is this so? Since booleans are defined for the entire run () method, should they not be called by the while loop, even if it is outside the while loop?

import acm.program.*; import acm.graphics.*; import java.awt.*; public class BouncingBallv3 extends GraphicsProgram { public void run() { double x = (getWidth() - BALL_SIZE)/2 ; //sets the starting position of ball at center double y = (getHeight() - BALL_SIZE)/2 ; GOval ball = new GOval (x, y, BALL_SIZE, BALL_SIZE ); // creates a red ball at center of screen ball.setFilled(true); ball.setColor(Color.red); add (ball); double dx = 1; //increments by which the ball moves double dy = 1; //declares boolean variables to test if ball position is at an edge boolean atHorizontalEdge = (ball.getX() == getWidth() - BALL_SIZE) || ball.getX() == 0 ; boolean atVerticalEdge = (ball.getY() == getHeight() - BALL_SIZE) || ball.getY() == 0 ; /* while loop keeps the ball moving in direction dx,dy * if ball reaches a position at any edge, the direction dx or dy changes */ while (true) { if (atHorizontalEdge) { //changes direction of ball if it hits a left/right wall dx = -dx; } else if (atVerticalEdge) { //changes direction of ball if it hits a top/bottom wall dy = -dy; } ball.move(dx,dy); pause (PAUSE_TIME); } } private static final double BALL_SIZE = 50; private static final int PAUSE_TIME = 5; } 
0
source share
3 answers

The problem is not that the declaration of Boolean elements is outside the while loop. This means that you are checking your boundaries outside the while loop. Because of this, your state is never updated, and it only checks the initial state of the ball.

+4
source

You should update atHorizontalEdge and atVerticalEdge in the body of the loop after each iteration, I think.


UPDATE:

The body of the while loop should be like this, `// declare booleans to check if the position of the ball is on the edge boolean atHorizontalEdge = false; boolean atVerticalEdge = false;

  /* while loop keeps the ball moving in direction dx,dy * if ball reaches a position at any edge, the direction dx or dy changes */ while (true) { atHorizontalEdge = (ball.getX() == getWidth() - BALL_SIZE) || ball.getX() == 0; atVerticalEdge = (ball.getY() == getHeight() - BALL_SIZE) || ball.getY() == 0; if (atHorizontalEdge) { //changes direction of ball if it hits a left/right wall dx = -dx; } else if (atVerticalEdge) { //changes direction of ball if it hits a top/bottom wall dy = -dy; } ball.move(dx,dy); pause (PAUSE_TIME); }` 

The reason it works is if you define the inner loop atHorizontalEdge and atVerticalEdge , because each iteration of these two variables is recalculated (i.e. updated).

0
source

atHorizontalEdge and atVerticalEdge can be declared inside or outside the while , which is not important.

It is important that the following calculation only once before the cycle begins:

 atHorizontalEdge = (ball.getX() == getWidth() - BALL_SIZE) || ball.getX() == 0 ; atVerticalEdge = (ball.getY() == getHeight() - BALL_SIZE) || ball.getY() == 0 ; 

Therefore, atHorizontalEdge and atVerticalEdge will have the same value from the beginning to the end of your run method (which is forever).

You obviously want these two lines to be executed at each iteration in your loop, since they will not be updated on their own ...

 while (true) { atHorizontalEdge = (ball.getX() == getWidth() - BALL_SIZE) || ball.getX() == 0 ; atVerticalEdge = (ball.getY() == getHeight() - BALL_SIZE) || ball.getY() == 0 ; ... } 


EDIT: Also, it would be better to check if x and y were greater than or equal to width / height and less than or equal to 0 for two reasons:

  • If you decide to change the increment from 1, you can skip this exact value and cause an error, but more importantly:
  • You are using double , and the number of floating point numbers may differ from what you are comparing, therefore == may cause errors, and the ball may go past the edge and keep happening.

i.e. ball.getX() >= getWidth() ... ball.getX() <= 0

What Every Computer Scientist Should Know About Floating-Point Arithmetic

0
source

All Articles