import acm.graphics.*; import acm.program.*; import java.awt.*; import java.awt.event.*; import java.util.*; public class BouncingBalls extends GraphicsProgram { public void run() { Random rand = new Random(); for(int i = 0; i < 10; i++) { double x = rand.nextDouble() * (this.getWidth() - 20); double y = rand.nextDouble() * (this.getHeight() - 20); this.add(new Ball(x, y, 20)); } while(true) { this.pause(40); for(int i = 0; i < this.getElementCount(); i++) { Ball b = (Ball) this.getElement(i); b.updateDirection(this); } for(int i = 0; i < this.getElementCount(); i++) { Ball b = (Ball) this.getElement(i); b.step(); } } } } class Ball extends GOval { private double direction; public Ball(double x, double y, double diam) { super(x, y, diam, diam); setFilled(true); setFillColor(Color.RED); direction = 2 * Math.PI * Math.random(); } public void updateDirection(GraphicsProgram win) { if(this.getX() < 0 || this.getX() + this.getWidth() > win.getWidth()) { direction = Math.PI - direction; } if(this.getY() < 0 || this.getY() + this.getHeight() > win.getHeight()) { direction = -direction; } double myRad = this.getWidth() / 2; for(int i = 0; i < win.getElementCount(); i++) { Ball b = (Ball) win.getElement(i); if(b != this) { double bRad = b.getWidth() / 2; double dx = (b.getX() + bRad) - (this.getX() + myRad); double dy = (b.getY() + bRad) - (this.getY() + myRad); if(dx * dx + dy * dy < (myRad + bRad) * (myRad + bRad)) { direction = Math.PI + direction; } } } } public void step() { this.move(5 * Math.cos(direction), 5 * Math.sin(direction)); } }