クリック数などを表示する

終了処理

終了した時にクリアできたことを表示して栄誉をたたえることもゲームの要素です。とりあえず Cleard と表示しましょう。

run()メソッドのwhileが終わった時がクリアです。Cleardを表示する部分はそこに書くのが適当です。

@Override
public void run() {
    while ( tmax > clearct ){
        前回のを四角で消す
        クリアしていない障害物を描きなおす
        障害物に衝突していたらクリアを記録し四角で消す
        greenボタンをクリックしていたらdx,dyを交換し正負反転する
        blueボタンをクリックしていたらdx,dyを交換する
        xにdxを加え、パネルからはみ出したら跳ね返らせる
        yにdyを加え、パネルからはみ出したら跳ね返らせる
        を描く
        何ミリ秒か待つ
    }
    Cleardと表示する。
}

ファイル名 ABall4.java の一部

    } //end of while
    // Cleardと表示する。
    int sx = xmax/4;
    int sy = ymax/4;
    thg.drawString("Cleared",sx,sy);
      // ↑ sx,sy に Cleared と書く 
    mypnl.repaint();
} //end of run()

moveDisk

場所は上から高さの1/4、左から幅の1/4の位置です。場所はいいのですが、文字が小さすぎます。これはBufferedImageの大きさがパネルの2倍あり、それを縮小して描いているからです。

文字の大きさを指定するにはいくつか方法があるようですが、Fontクラスを使うのが手軽です。図形の色の指定に似ています。

Font f=new Font(フォント名,スタイル,サイズ);
//Font(String name, int style, int size) 
thg.setFont(f);

フォント名は"courier","TimesRoman"のような個別の名前も使えますが、セリフ、サンセリフなどの種類の名前も使えます。これは予めjavaが定数として設定しています。クラス名Fontをつけて使います。

Font.SERIF 
Font.SANS_SERIF
Font.MONOSPACED
Font.DIALOG 

スタイルは太字とか斜体などの設定です。これも予めjavaが定数として設定しています。クラス名Fontをつけて使います。

Font.PLAIN 
Font.BOLD 
Font.ITALIC

サイズはデフォルトで12になっているようです。

とりあえず、ymax/8にしておきます。BufferedImageにあわせて決めないとBufferedImageが変わったときに小さくなったりはみ出したりしてしまいます。

ついでに色も変えました。

ファイル名 ABall4.java の一部

int sx = xmax/4;
int sy = ymax/4;
Font f=new Font(Font.SANS_SERIF,Font.PLAIN,ymax/8);
thg.setFont(f);
thg.setColor( new Color(255,153,51) );
thg.drawString("Cleared",sx,sy);
mypnl.repaint();

moveDisk

成績も

このとき、同時にクリックした回数や、壁に跳ね返った数を別々に、あるいはその合計数をも表示する様に工夫します。この数を少なくすることを競うゲームとします。たとえばCleardに加えて

ファイル名 ABall4.java の一部

int sx = xmax/4;
int sy = ymax/4;
Font f=new Font(Font.SANS_SERIF,Font.PLAIN,ymax/8);
thg.setFont(f);
thg.setColor( new Color(255,153,51) );
thg.drawString("Cleared",sx,sy);
thg.drawString("Click  "+(greenct+bluect),sx,sy+ymax/8);
     // ↑ sy+ymax/8 で1行下の場所を求め クリック数を書く
thg.drawString("Bounce "+bouncect,sx,sy+ymax/4); 
     // ↑ sy+ymax/4 で2行下の場所を求め 壁に当たった数 bouncect を書く
mypnl.repaint();

moveDisk

もちろんbouncectは予め宣言をし、数えておく必要があります。

宣言と初期化はMoveDiskのフィールドか、run()メソッドの最初に置きます。

int bouncect=0;

あとは跳ね返りの処理をしているところ(複数あります)に bouncect++; と書くだけです。

正しく数えているかはゲームを何度かやってみるとわかります。

課題

1.

上記の様に働くようにし、動作を確認しなさい。

ファイル名 ABall4.java

クリアまでの時間の計り方

クリアまでの時間を競うというのもゲームのよくあるパターンです。やってみましょう

System.currentTimeMillis()は現在時をミリ秒単位で知らせてくれます。戻り値はintでなくlongです。(実際には1970年1月1日からの現在までの経過時間を返します)

ゲームの最初に

long time0 = System.currentTimeMillis();

として時刻を記録し、ゲームの終わりに、

long time1 = System.currentTimeMillis();

として時刻を再度記録します。

time1-time0

は、かかった時間をミリ秒単位で計測したものになります。つまり16000となれば16秒ということです。

普通は1000で割って秒に直します。

(time1-time0)/1000

longとintの計算なので整数に切り捨てられます。

少数点以下も表現したいときは次のようにします。

(time1-time0)/1000.0

実際のプログラム

ファイル名 ABall5.java の一部

run()のwhileの前に

long time0 = System.currentTimeMillis();

whileの{ }の後に、

long time1 = System.currentTimeMillis();

結果を整数にして良ければ次のように表示するのが簡単でしょう。long÷intはlongになりますからStringと+演算で整数として連結されます。小数も同様な方法で出せますが、その場合は桁数のコントロールをしないとはみ出します。

ファイル名 ABall5.java の一部

Font f=new Font(Font.SANS_SERIF,Font.PLAIN,ymax/8);
thg.setFont(f);
thg.setColor( new Color(255,153,51) );
thg.drawString("Cleared",                   sx,sy         );
thg.drawString("Click  "+(greenct+bluect),  sx,sy+ymax/8  );
thg.drawString("Bounce "+bouncect,          sx,sy+ymax/4  );
thg.drawString("Time "+((time1-time0)/1000),sx,sy+ymax/8*3); 
mypnl.repaint();

moveDisk

課題

2.

上記の様に働くようにし、動作を確認しなさい。

ファイル名 ABall5.java


Javaプログラミング
聖愛中学高等学校
http://www.seiai.ed.jp/
Dec.2003
Oct.2010
Oct.2012