2012年2月15日水曜日

定期処理ハンドラ

サンプルの「Snake」を題材として、アプリ作成の基本をまとめるシリーズです。

第二回目は「定期処理ハンドラ」です。

定期処理ハンドラとは、Handlerクラスを利用して、一定の間隔で処理を行わせる仕組みのことです。

例えば、場面場面でキャラクターの出現数の違いによって、処理の重さが異なる場合があります。
処理の重さの違いでキャラクターの動きにムラは出したくありません。
また、端末の処理能力の違いでキャラクターの動く速度が変わってしまうことも避けたいです。

その解決方法の一つとして、定期処理ハンドラの仕組みがあります。
「Snake」では、以下のように定期処理ハンドラを使用しています。

【SnakeView.java】

class RefreshHandler extends Handler {

@Override
public void handleMessage(Message msg) {
SnakeView.this.update();
SnakeView.this.invalidate();
}

public void sleep(long delayMillis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), delayMillis);
}
};


public void update() {
if (mMode == RUNNING) {
long now = System.currentTimeMillis();

if (now - mLastMove > mMoveDelay) {
clearTiles();
updateWalls();
updateSnake();
updateApples();
mLastMove = now;
}
mRedrawHandler.sleep(mMoveDelay);
}
}


sendMessageDelayedメソッドによって、指定時間(delayMillis)後にMessageオブジェクトを送信しています。
Messageオブジェクトは、handleMessageオブジェクトで受信されます。
handleMessageオブジェクトから呼び出されるupdateメソッドでsendMessageDelayedメソッドを呼び出しています。
これを繰り返すことで、指定時間(delayMillis)の間隔で定期的な処理を実現しています。

この定期処理の中で、アップデートやViewの再描画を実施しています。
SnakeView.this.update();
SnakeView.this.invalidate();

前回のアップデートからの経過時間が指定時間(mMoveDelay)より大きい場合のみ、アップデートを実施すれば更新間隔を一定に保つことができます。

sendMessageDelayedメソッドによって送信するMessageオブジェクトは、以下のpublicなフィールドを持つMessageクラスのオブジェクトです。

public int what;
public int arg1;
public int arg2;
public Object obj;

フィールドには、sendMessageDelayedメソッドによって引き渡したい値を代入します。
定期処理を実現するだけならば、引き渡す値は何でもかまいません。
「Snake」では、what=0の値を送信しています。


因みに、指定時間(mMoveDelay)は、以下のように初期設定してあります。
mMoveDelay = 600;

アップデート処理の中で、ヘビがリンゴを食べる度に指定時間(mMoveDelay)を減少させています。
mMoveDelay *= 0.9;

次第に定期処理の間隔を短くして、ヘビの動きを速くすることで、ゲームの面白さを実現しています。


最後に、Messageオブジェクトの詳細です。

Messageオブジェクトの作成とフィールド値の設定は以下のようにします。

Message msg = new Message();
msg.what=123;
msg.arg1=1;
msg.arg1=2;
msg.obj="object";

obtainMessageメソッドを利用すれば、以下のように簡単に出来ます。

Message msg = obtainMessage(123,1,2,"object");


obtainMessageメソッドは以下のようにオーバーロードされています。

obtainMessage(int what)
obtainMessage(int what, Object obj)
obtainMessage(int what, int arg1, int arg2)
obtainMessage(int what, int arg1, int arg2, Object obj)


「Snake」では、obtainMessage(int what)でオブジェクトの作成とフィールド値の設定を行っています。

0 件のコメント:

コメントを投稿