2014年4月12日土曜日

モグラ叩きゲームで学ぶアンドロイドプログラミング (4/8)

前回に引き続き、今回は、タイマーの処理を実装します。

全体のソースコードは以下にあります。
https://gist.github.com/mrp1q7z/cdae635e02c16c1cb9e9


画面 (activity_main.xml) を一部修正します。
残り時間を表示するテキストにID(名前)を付けます。
IDはプログラムから参照するものだけ付けます。
参照しないものについては付けなくてもOKです。

「timeText」という名前にしました。



次に、プログラムから残り時間を操作するための変数を定義します。(17行目)
private TextView mTimeText;

定義した変数に値をセットします。(27行目)
mTimeText = (TextView) findViewById(R.id.timeText);

次に、残り時間をカウントダウンするための変数を定義します。(18行目)
private int mGameTime = 60;
あらかじめ「60」とう値をセットしていますが、これは60秒という意味です。
この値を変えると残り時間を変更することができます。

次に、タイマーのような一定時間で処理を繰り返すには「Timer」というクラスを使います。そのための変数を定義します。(19行目)
private Timer mTimer = null;

次に、「gameStart」というメソッドを追加して、ゲームスタート時の処理を記述します。(64〜86行目)

private void gameStart() {
        printMole();

        if (mTimer != null) {
            return;
        }
        mTimer = new Timer(true);
        mTimer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mGameTime--;
                        if (mGameTime <= 0) {
                            gameOver();
                        }
                        mTimeText.setText(Integer.toString(mGameTime));
                    }
                });
            }
        }, 1000, 1000);

}

65行目:モグラを表示するメソッド「printMole」を呼びます。(前回、onResumeから呼び出していたもの)

67〜69行目:すでにタイマーがスタートしているかを判定し、すでにスタートしている場合は処理を抜けます。

70行目:タイマー変数の初期化

71行目:scheduleAtFixedRate(TimerTask task, long delay, long period)は、delayミリ秒あとの時間を基準としてperiodミリ秒単位でタスクを繰り返す。今回の場合だと、71行目の「new TimerTask() {」〜85行目の「}」までがタスクで、85行目の1つめの1000がdelay、2つめの1000がperiodになります。

タスクの中では、mGameTimeをカウントダウンして(77行目)
0以下になったら gameOver メソッドを呼び出して(78〜80行目)
残り時間を画面に表示(81行目)
しています。

途中の run() を Override していたり、
mHandler.post() だったりは
意味が分からなくてもこんなもんだと思っていただければOKです。

次に、「gameOver」メソッドを追加し、ゲーム終了時の処理を記述します。(88〜91行目)
private void gameOver() {
        mTimer.cancel();
        mTimer = null;
}


タイマーをキャンセルして、変数をヌルで初期化しています。

最後に、onResume の printMole を gameStart に置きかえます。(96行目)
protected void onResume() {
        super.onResume();
        gameStart();
}


ここまでできたら実行してみましょう。
Time が1秒づつ減っていくと思います。


今日はここまで。次回に続く。