import java.applet.*; import java.awt.*; /** * An interesting interactive graphical trick with balls. * * By Kirk Israel * August 8 2000 * * Permission is given to do whatever you want with this code, as * long as you drop me an e-mail * * this code triggers some deprecation warnings, ah well! */ public class ballcan extends Applet implements Runnable { //1000 balls should be plenty int ballx[] = new int[1000]; int bally[] = new int[1000]; int ballxspeed[] = new int[1000]; int ballcount = 0; int center = 0; //these, and the graphical update delay, //should be parameters but I'm feeling lazy int ballsize = 2; int gravity = 5; Dimension size; Image buffer; Graphics bufferGraphics; Thread animator; boolean please_stop; /** setup offscreen image for double buffering **/ public void init(){ size = this.size(); buffer = this.createImage(size.width,size.height); bufferGraphics = buffer.getGraphics(); //record position of center line center = size.width/2; } /** Clear offscreen buffer, paint in balls, and slap the whole image into the screen buffer **/ public void paint(Graphics g){ //clear background bufferGraphics.setColor(Color.black); bufferGraphics.fillRect(0,0,size.width,size.height); drawBalls(); g.drawImage(buffer,0,0,this); } /** don't erase screen on update, just call paint **/ public void update(Graphics g) { paint(g); } public void run(){ while(! please_stop){ moveBalls(); repaint(); try { Thread.sleep(50); } catch(InterruptedException e) {;} } animator = null; } public void start(){ if(animator == null) { please_stop = false; animator = new Thread(this); animator.start(); } } public void stop() { please_stop = true; } /** add a ball on mouse down **/ public boolean mouseDown(Event e, int x, int y){ if(ballcount < 1000) { ballx[ballcount] = x; bally[ballcount] = y; ballxspeed[ballcount] = 0; ballcount++; } return true; } /**paint each ball in its current position**/ private void drawBalls() { bufferGraphics.setColor(Color.white); for(int i = 0; i < ballcount; i++){ bufferGraphics.drawOval(ballx[i]-ballsize, bally[i]-ballsize, ballsize*2, ballsize*2); } } /** each ball to the left of center has it's velocity increased to the right, and vice versa **/ private void moveBalls() { for(int i = 0; i < ballcount; i++){ if(ballx[i] < center) ballxspeed[i] = ballxspeed[i] + gravity; if(ballx[i] > center) ballxspeed[i] = ballxspeed[i] - gravity; ballx[i] += ballxspeed[i]; } } }