数字順押しゲームを作ってみよう4

   2014/04/14

タイムを競うゲームはたくさんあります。数字が出ると1秒でも、
いや0.1秒でも速く、とやる程に燃えますね。

毎度、管理人イガジーです。
タッチタイプトレーナt3jar
↑にもタイム測定&ランキングを追加するバージョンアップを検討中です。

という訳で、数字順押し(番号探し)ゲームにタイム測定の処理を追加します。
「時間測定の開始」は [1]が押された時なので、
フィールドに long t0; を置いてclass Nbtn のactionPerformed() に
if (n==1) t0=System.currentTimeMillis();とすれば良いでしょう。
n は、Nbtn自身が何の数字を受け持っているか、を保持している変数です。

同様に「時間測定の終了」は 最後のキー[16]が押された時ですから

++p;
if (p<16) {
	sc.setText("click "+Integer.toString(p));
}else{
	long t1=System.currentTimeMillis();
	sc.setText(Long.toString(t1-t2)+" ms");
}

とすれば良いですね。

ただ、普通の人にはミリ秒(ms)は馴染みが薄いので、小数点付きの秒表示
例えば、”13.092 s” などと表示させることにしましょう。
その処理は、浮動小数点演算を使うのもひとつの方法ですが
整数演算(固定小数点)で処理することもできます。

秒の整数部は、ms を 1000で割った「商」で得られます。
小数点以下の部分は、ms を 1000で割った「余り」で得られます。
ただし、小数点以下を表示する場合は、0 を補う必要があります。
例えば、1000で割った余りが92の時は 092 と表示しなければなりませんし
余りが1なら 001です。余りが0の時も 000 と表示するのが良いでしょう。

0を補うには、”00″+Long.toString(t2%1000); と左に”00″をくっつけておいて
substring()を使って、右から3文字ぶんを取り出せばOKです。

ここまでのソースコードを掲載しておきます。

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;

public class ClickN3 extends Frame {
	private static final long serialVersionUID = 1L;
	Label sc;
	Nbtn []nb = new Nbtn[16];
	Random rnd;
	int p=1;
	long t0;

	ClickN3(){
		this.setTitle("Click N");
		this.addWindowListener(new WindowAdapter(){
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		rnd=new Random();
		sc=new Label("click 1");
		sc.setFont(new Font(Font.DIALOG,Font.PLAIN,28));
		sc.setAlignment(Label.CENTER);
		Panel p1=new Panel();
		Panel bp=new Panel(new GridLayout(4,4));
		for (int i=0;i<16;++i) {
			nb[i]=new Nbtn(i+1);
			bp.add(nb[i]);
		}
		shuffle(32);
		Button rst=new Button("Reset");
		rst.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				for (int i=0;i<16;++i) nb[i].setBackground(Color.YELLOW);
				shuffle(32);
				p=1;
				sc.setText("click "+Integer.toString(p));
			}
		});
		p1.add(rst);
		this.add(p1,BorderLayout.SOUTH);
		this.add(bp,BorderLayout.CENTER);
		this.add(sc,BorderLayout.NORTH);
		this.setSize(200,250);
		this.setVisible(true);
	}

	void shuffle(int count) {
		int b1,b2;
		for (int i=0;i<count;++i) {
			b1=rnd.nextInt(16);
			b2=rnd.nextInt(16);
			if (b1!=b2) {
				int t1=nb[b1].getn();
				int t2=nb[b2].getn();
				nb[b2].setn(t1);
				nb[b1].setn(t2);
			}
		}
	}
	public static void main(String[] args) {
		new ClickN3();
	}
	class Nbtn extends Button  implements ActionListener{
		private static final long serialVersionUID = 1L;
		int n;
		Nbtn(int nn) {
			super(Integer.toString(nn));
			n=nn;
			this.setFont(new Font(Font.DIALOG,Font.BOLD,16));
			this.setBackground(Color.YELLOW);
			this.addActionListener(this);
		}
		int getn() {	return n; }
		void setn(int nn) {
			n=nn;
			setLabel(Integer.toString(n));
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			if (p==n) {
				if (n==1) t0=System.currentTimeMillis();
				setBackground(Color.GRAY);
				++p;
				if (p<17) {
					sc.setText("click "+Integer.toString(p));
				}else{
					long t1=System.currentTimeMillis();
					long t2=t1-t0;
//					sc.setText(Long.toString(t2)+" ms");
					// 小数点付きの秒表示にする
					String ss=Long.toString(t2/1000);
					String ms="00"+Long.toString(t2%1000);
					sc.setText(ss+"."+ms.substring(ms.length()-3)+" s");
				}
			}
		}
	}// class Nbtn
}

コメント一覧

  1. Gypsyman より:

    JFileChooserの拡大についての質問

    ディスプレイの解像度の拡大に伴いJFileChooserを呼び出しても通常ではサイズが小さいために任意の大きさに拡大表示する方法で悩んでいます。
    以下のコードではJFileChooserのフォントサイズの拡大やボタンの拡大は出来たのですが、アイコンの拡大が出来ていない状態です。
    (以下、管理人により割愛)

    • igazeey より:

      Gypsyman さん、管理人イガジーです。
      頂いたコメントはこのエントリとは関係しないので
      新しい記事として掲載しました。
      こちらをご覧ください。

この記事へのコメントはこちら

メールアドレスは公開されませんのでご安心ください。
また、* が付いている欄は必須項目となりますので、必ずご記入をお願いします。

内容に問題なければ、下記の「コメント送信」ボタンを押してください。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)