/** [BufferTest.java] Copyright(c) 2000-2004 WakuWaku. */ import java.awt.*; import java.applet.Applet; import java.util.Random; public class BufferTest extends Applet implements Runnable { final static int MAX = 10, SZ = 38; //左からボールの最大表示数, ボールのサイズ final static Color[] COL = new Color[SZ]; Graphics gBuf; //オフスクリーンバッファのグラフィックコンテキスト Image imgBuf; Thread thread = null; int[] x, y, m; //左からボールのX, Y座標, 移動量 int w, h; static { for(int i = 0; i < SZ; i++) { int c = 255 - i * 255 / (SZ - 1); COL[i] = new Color(c, c, 255 - c); } } public void init() //アプレットの初期化時呼び出される { Dimension d = getSize(); //アプレットサイズ取得 this.w = d.width; this.h = d.height; //オフスクリーンバッファ(以下バッファ)の作成 imgBuf = createImage(w, h); //バッファ生成 gBuf = imgBuf.getGraphics(); //グラフィックコンテキスト取得 } private void drawBackImage(Graphics g) //背景イメージ描画メソッド { Random rand = new Random(123); //種を固定 for(int i = 0; i < h; i++) { g.setColor(new Color(0, 0, (int)(rand.nextFloat() * 255))); g.drawLine(0, i, w, i); } g.setFont(new Font("Arial", Font.ITALIC, 48)); g.setColor(Color.gray); g.drawString("Buffer Test", 40, h / 2 + 16); } public void start() //アプレットが表示されると呼び出される { if(thread == null) { thread = new Thread(this); //スレッドの生成 thread.start(); //スレッドを開始させ、runメソッドを呼び出す } } public void run() //メインルーチン { //ボール初期化 Ball[] ball = new Ball[MAX]; for(int i = 0; i < MAX; i++) ball[i] = new Ball(-99, 0, 0); //背景画像の作成 Image imgBack = createImage(w, h); //背景画像生成 Graphics gBack = imgBack.getGraphics(); //グラフィックコンテキスト取得 drawBackImage(gBack); gBack.dispose(); //グラフィックコンテキスト破棄 int wait = 0; Random rand = new Random(456); //種を固定 while(thread != null) { wait--; gBuf.drawImage(imgBack, 0, 0, this); //背景画像をバッファに描画 for(int i = 0; i < MAX; i++) { Ball target = ball[i]; if(target.x == -99 && wait < 0) { target.x = -SZ; target.y = (int)(rand.nextFloat() * (h - SZ)); target.move = (int)(rand.nextFloat() * 7) + 2; wait = (int)(rand.nextFloat() * 20) + 4; }else { target.move(); //ボールを移動 if(target.x > w) target.x =- 99; for(int r = SZ - 1; r >= 0; r--) { gBuf.setColor(COL[r]); //ボールの色設定 gBuf.fillOval(target.x + (SZ - r) / 2, target.y + (SZ - r) / 2, r, r); //ボールをバッファに描画 } } } repaint(); //画面の強制更新 try { Thread.sleep(50); //0.05秒間スリープ。これを忘れるとハングアップする }catch(InterruptedException e) {} } } public void update(Graphics g) //オーバーライドして最低限のことだけをする { paint(g); } public void paint(Graphics g) { g.drawImage(imgBuf, 0, 0, this); //バッファを画面に描画 } public void stop() //アプレットが画面から消えると呼び出される { if(thread != null) thread = null; } } //一つのボールを表すクラス class Ball { int x; //x座標 int y; //y座標 int move; //x方向への移動量 public Ball(int x, int y, int move) { this.x = x; this.y = y; this.move = move; } //ボールを移動 public void move() { this.x += this.move; } }