Android携帯ゲームを作って世界に配信してみよう(番外編) ―― Androidアプリのライフサイクル
●ゲーム・ループでUIイベントを処理
ゲーム・ループでは,ユーザの入力処理やオブジェクトの移動・判定処理を行い,最後に描画処理を行います.ゲーム・ループは,Android OSから呼び出されるユーザ・インターフェース系の処理用のスレッドとは別に,並列処理を行うための専用のスレッドを生成して,ゲーム・ループのすべての処理を行います.まず,ユーザが画面をタッチした際に,それをどのようにゲーム・ループ内で処理するかを説明します.
1)ユーザが,画面をタッチする
2)Android OSは,タッチされた画面の個所に配置されているViewクラスのonTouchメソッドをコールバック呼び出しする
3)onTouchメソッドでは,処理はいっさいせず,Mainクラスのイベント・キューに格納する(リストD,リストE).ユーザ・インターフェース・スレッドでの処理は,これで完了
4)ゲーム・ループ専用のスレッドにて,ループのたびに,イベント・キューからタッチ・イベントを取り出し,必要な処理を行う
リストD タッチ・イベントをキューに格納(DribbleActivity.javaより抜粋)
class DribbleView extends SurfaceView implements SurfaceHolder.Callback { @Override public boolean onTouchEvent(final MotionEvent event) { Main.queue(event); return true; } } |
リストE タッチ・イベントをキューに格納(Main.javaより抜粋)
public static synchronized void queue(final MotionEvent event) { events.add(event); } |
ゲーム・ループ内では,毎処理フレームごとに,現在の画面遷移状態を管理するSceneクラスのprocessメソッドを呼び出し,画面に依存した処理を委譲します(リストF).例えば,タイトル画面の処理を行う,TitleSceneクラスのprocessメソッドでは,先ほどキューに格納したイベントを1件取り出してイベントの種類を調べ,タッチ・イベントであればタッチ音を再生して,次のゲーム・プレイ画面へ遷移します(リストG,リストH).
リストF processメソッドを呼び出して画面処理を委譲する(Main.javaより抜粋)
public static void runLoop() { : for (;;) { : final Scene scene = current; scene.process(view); : } : } |
リストG 入力イベントを判定して適切な効果音を再生する(TitleScene.javaより抜粋)
public void process(SurfaceView view) { final MotionEvent e = Main.event(); if (e != null && e.getAction() == MotionEvent.ACTION_UP) { Sounds.playTouch(); Main.startScene(Main.PLAY); } } |
リストH キューからイベントを1件取得する(Main.javaより抜粋)
public static synchronized MotionEvent event() { return events.poll(); } |
ちなみに,TitleSceneクラスは,Sceneクラスを継承する形で作ったサブクラスです(図B).
図B 本アプリにおけるSceneクラスのサブクラス
