単純にupdate()を上書きするだけでは上手くいかないので、他の方法を考えます。
何の工夫もしないアプレットではrepaint()を呼ぶとアプレット全体を再描画します。ここでアプレット全体でなく、必要な部分だけを再描画するようにすれば、全体の処理時間が短くなり、結果的にチラツキが減って見えるはずです。
このように描画を領域の一部に絞ることを「クリッピング」というそうです。私はJava言語入門で知りました。
ボールが移動したときにしたいことは
なので、再描画が必要なのは「前にボールがあった位置」と「新しいボールの位置」です。この二つを別々に指定するのは面倒なので、この二つを含む最少の長方形をクリップします。
repaint()を呼ぶと直ちにpaint()が呼ばれていればこれで良いのですが、諸般の事情により次のrepaint()までpaint()の呼び出しがスキップされる場合があります。
そのため実際には「前にボールがあった位置」ではなく「最後に描画したときにボールがあった位置」と「新しいボールの位置」を含む長方形をクリップします。
まずインスタンス変数
int lastPaintedX, lastPaintedY;
を導入し「最後に描画したときにボールがあった位置」を記憶させます。
update()を上書きして、その中で
int minX = x < lastPaintedX ? x : lastPaintedX; int maxX = x > lastPaintedX ? x : lastPaintedX; int minY = y < lastPaintedY ? y : lastPaintedY; int maxY = y > lastPaintedY ? y : lastPaintedY; g.clipRect(minX, minY, maxX - minX + r, maxY - minY + r);
必要な領域をクリップしています。最初の4行で描画が必要な長方形の座標を求め、最後の一行
g.clipRect(minX, minY, maxX - minX + r, maxY - minY + r);
でクリッピングをしています。
update()を上書きしているので、デフォルトのupdate()でなされる処理
g.setColor(getBackground()); g.fillRect(0, 0, width, height);
もこの中で行ないます。しかし、クリッピングを行なったあとなので、実際に描画が行なわれるのはクリップした長方形の内部だけです。
最後にpaint()の中で
lastPaintedX = x; lastPaintedY = y;
として「最後に描画したときにボールがあった位置」を記憶させています。