解決策その2の続き。
クリア後、押せなくしたstartのボタンを元に戻してもう一度できるようにします。。
まずwhileを終わらせなければなりません。whileを終わらせるとrunメソッドは終了となり、このスレッドはなくなります。なくる前にボタンを有効にする必要があります。
前回書いた終了処理の部分です。クリック数などを書く場所を真ん中からボールの位置近くに変更しました。クリア時のボールが右端や下端に近いと書けませんから、その場合はずらします。
クリック数はgctgrn+gctblu、跳ね返り数はbnct、bnctは変数として適当な場所で宣言しておきます。
if (clct==tmax) { int sx = x+8; if (sx>image.getWidth()-60) sx=image.getWidth()-60; int sy = y+16; if (sy>image.getHeight()-60) sy=image.getHeight()-60; thg.drawString("Cleared",sx,sy); thg.drawString("Click "+(gctgrn+gctblu),sx,sy+16); thg.drawString("Bounce "+bnct,sx,sy+16*2); rbtn.setEnabled(true); rbtn.setText("replay"); }
ボタンの有効化はsetEnabled(true)、ボタンの文字はreplayにしておきます。
whileを終わらせるにはtrueを変更する必要があります。終了処理でbreakで抜けることもできますが、whileにいつ終わるのかを書く方がプログラムの流れを掴むことができて優れています。boolean cleared のような変数を用意してif(clct==tmax){}の中で変更する方法もありますが、ここではisEnabled()を使ってみます。setEnabled()でtrueになっているかどうかを問うメソッドです。
rbtn.isEnabled()でrbtnが有効ならtrue, 無効ならfalseが返ります。これを ! で反転させて false の間繰り返すことにします。
//while ( true ){ while ( ! rbtn.isEnabled() ){
isEnabled()を使った関係で、actionPerformed()のスレッドをスタートする部分の順番が問題になります。
スレッドをスタートする前にsetEnabled(false)をしておかないとすぐwhileが終了してしまうからです。
各種カウンタの値もここでゼロに戻します。
public void actionPerformed(ActionEvent e) {
if (e.getSource() == rbtn) {
clct=0;
gctblu=0;
gctgrn=0;
bnct =0;
rbtn.setEnabled(false);
rbtn.setText("busy");
Thread thread = new moveDisk(mypnl,buffimg);
thread.start();
}
前回の表示が残っています。
runメソッドのwhileの前、障害物を描く前に背景色で塗りつぶす作業を加えます。
Color bc= new Color(255,255,191); //背景の色 thg.setColor(bc); thg.fillRect(0,0,image.getWidth(),image.getHeight()); thg.setColor(Color.blue); for(int i=0 ; tmax>i ; i++){ if (ts[i].cleared) continue; thg.fillOval(ts[i].x-d/2,ts[i].y-d/2,d,d); }
MoveDisk8.javaに書き加えます。
上記の様に働くようにし、動作を確認しなさい。