This program creates a beautiful animation of colorful bouncing balls. The finished product could definitely make a solid screen saver.

We'll have to generate 50 circles and place them randomly about the canvas. Note that in addition to creating the balls, we'll also need to generate initial x and y velocities for each ball. These velocities should be random. Importantly, we will store the balls and velocities in three ArrayLists. We can decompose all of this into a method.

On each iteration of the animation while loop, we'll also need to check for bounces on all of the balls using an inner for loop.

Solution

/**
 * Class: BouncingBalls
 * -----------------
 * A program that bounces many balls simultaneously around the screen.
 */
public class BouncingBalls extends GraphicsProgram {
	private static final double BALL_SIZE = 20;
	private static final double N_BALLS = 50;

	private ArrayList balls;
	private ArrayList ballVx;
	private ArrayList ballVy;
	private RandomGenerator rg = new RandomGenerator();

	public void run() {
		createBalls();
		while(true) {
			animateBalls();
			pause(10);
		}
	}

	private void animateBalls() {
		for(int i = 0; i < N_BALLS; i++) {
			GOval ball = balls.get(i);
			if(ball.getX() + ball.getWidth() > getWidth() || ball.getX() < 0) {
				reflectX(i);
			}
			if(ball.getY() + ball.getHeight() > getHeight() || ball.getY() < 0) {
				reflectY(i);
			}
			ball.move(ballVx.get(i), ballVy.get(i));
		}
	}

	private void reflectY(int i) {
		ballVy.set(i, -ballVy.get(i));
	}

	private void reflectX(int i) {
		ballVx.set(i, -ballVx.get(i));
	}

	private void createBalls() {
		balls = new ArrayList();
		ballVx = new ArrayList();
		ballVy = new ArrayList();
		for(int i = 0; i < N_BALLS; i++) {
			double x = rg.nextDouble(0, getWidth() - BALL_SIZE);
			double y = rg.nextDouble(0, getHeight()- BALL_SIZE);

			double vx = rg.nextDouble(1, 7);
			if(rg.nextBoolean()) {
				vx *= -1;
			}
			double vy = rg.nextDouble(1, 7);
			if(rg.nextBoolean()) {
				vy *= -1;
			}

			GOval ball = new GOval(x, y, BALL_SIZE, BALL_SIZE);
			ball.setFilled(true);
			ball.setColor(rg.nextColor());
			add(ball);
			balls.add(ball);
			ballVx.add(vx);
			ballVy.add(vy);
		}
	}
}