import java.awt.*;
import java.awt.event.*;
import java.lang.*;

public class VariousBallsThread {

	public static void main(String[] args){
		VBalls f = new VBalls(400, 400); //(1)
		f.setSize(400, 400); //(2)
		f.addWindowListener(new WindowAdapter(){ //(3)
			public void windowClosing(WindowEvent e){
				System.exit(0);}});
		f.show();
	}
}


class VBalls extends Frame implements Runnable {

	Thread th;
	Ball ball[] = new Ball[100];
	int numBall = 0;
	Image buffer;                   
	Graphics offg;                   
	int width, height;    
          


	VBalls(int width, int height) {   
		this.width = width;
		this.height = height;

	
		th = new Thread(this);
		th.start();
	}

	public void run() {

		int slot = 0; 
		double randNum;
		int startX, startY;

		while (true) {

			if ( slot++ >= 20 ) {
				slot = 0;

				randNum = Math.random();
				startX = (int)Math.round(Math.floor(200*randNum));
				randNum = Math.random();
				startY = (int)Math.round(Math.floor(200*randNum));
	
				ball[numBall] = new Ball(startX, startY);
				numBall++;
			} 
			repaint();

			for(int i = 0; i < numBall; i++) {
				ball[i].move();
			}


			try {
				th.sleep(100);
			}
			catch (InterruptedException e) {}
		}



	}

	public void update(Graphics g) {
		paint(g);

	}

	public void paint(Graphics g) {

		if (offg == null) {
			buffer = createImage(width,height);
	  	offg = buffer.getGraphics();
		}

		offg.clearRect(0, 0, width, height);     //  NEW 

		offg.setColor(Color.black);               //  CHANGED
		offg.fillRect(200, 0, 10, 210);           //  CHANGED
		offg.fillRect(0, 200, 200, 10);           //  CHANGED

		for(int i = 0; i < 20; i++) {
			offg.drawLine(i * 10, 0, i * 10, 200); //  CHANGED
			offg.drawLine(0, i * 10, 200, i * 10); //  CHANGED
		}

		for(int i = 0; i < numBall; i++) {
			ball[i].display(offg);                //  CHANGED
		}
		g.drawImage(buffer, 0, 0, this);          //  NEW


	}


} // end of class VariousBalls






class Ball {
	int x, y;  // Ball の位置 (左上隅の座標)
	int size;  // Ball の大きさ (幅、高さ)
	Color c;   // Ball の色
    int xSpeed, ySpeed;  // Ball の速度 (x, y方向)
	int xMode, yMode;  //  動きのモード

	int shape;  //   0: まる, 1:四角



// コンストラクタ
	Ball(int xPosition, int yPosition) {
		x = xPosition;
		y = yPosition;
		c = Color.red;
		xSpeed = 3;
		ySpeed = 3;
		size = 10;
		xMode = 0;
		yMode = 0;
		shape = 0;
	}

// メソッド
	public void changeColor(Color nextColor) {
		c = nextColor;
	}

	public void changeSize(int nextSize) {
		size = nextSize;
	}

	public void changePosition(int nextX, int nextY) {
		x = nextX; 
		y = nextY;
	}

    public void changeSpeed(int nextXspeed,
						    int nextYspeed) {
		xSpeed = nextXspeed;
		ySpeed = nextYspeed;
	}

	public void move() {

		if (x + size > 200) {
			changeShape();
			xMode = 1;
		}
		if (y + size > 200 ) {
			changeShape();
			yMode = 1;
		}

		if (xMode == 0) {
			x = x + xSpeed;
		}
		else {
			x = x - xSpeed; 
		}

		if (yMode == 0) {
			y = y + ySpeed;
		}
		else {
			y = y - ySpeed; 
		}


	}


	void changeShape() {
		if (shape == 0) {
			shape = 1; 
		}
		else {
			shape = 0;
		}
	}


	public void display(Graphics g) {
		g.setColor(c);
		if (shape == 0 ) {
			g.fillOval(x, y, size, size);
		} 
		else {
			g.fillRect(x, y, size, size);
		}

	}

} //  end of class Ball




