Androidでゲーム作成(2)

昨日に引き続きAndroidでゲームを作るパターンを紹介します。
ゲームを作成する場合、なんらかのタイミングで画面を再描画していきますが、イベント駆動で再描画するパターンと一定周期で再描画するパターンの2つがあります。先に紹介したパターンはイベント駆動型で、キー入力をイベントに反応して再描画していました。これはカードゲームやシミュレーションゲームの場合には有効です。しかし、アクションゲームやシューティングゲームでは一定周期で再描画しなくてはなりません。そのような場合、描画用のメインループを作成するなどして、定期的な描画を行います。

D

メインループをどうやって実装するか?

メインループの実装方法は幾つかありますが、while文などを使った無限ループで実装する方法がメジャーです。Androidでも同じようにメインループを作ることができますが、独立したスレッドを立てて行う必要があります。surfaceCreated等で無限ループをしてしまったら、何時まで経っても初期化が終わりません。
スレッドはjava.lang.Threadを使えば簡単に作ることができますが、AndroidはJava5系のAPIを実装している為、java.util.concurrentパッケージのScheduledExecutorServiceを使った例を紹介します。

	private class GameBoadView extends SurfaceView implements
			SurfaceHolder.Callback {

		ScheduledExecutorService executor;

		public void surfaceCreated(SurfaceHolder holder) {
			executor = Executors.newSingleThreadScheduledExecutor();
			executor.scheduleAtFixedRate(new Runnable() {
				public void run() {
					for (Component reimu : alives) {
						reimu.move(frameCount);
					}
					repaint();
					frameCount++;
				}
			}, 200, 200, TimeUnit.MILLISECONDS);
		}

		public void surfaceDestroyed(SurfaceHolder arg0) {
			executor.shutdown();
		}
	}

surfaceCreatedでは、ScheduledExecutorService を作成し、その中に処理を記述したワーカーを登録しています。また、定期的な周期で実行されるようにスケジューリングしています(scheduleAtFixedRate)。その周期は、200ミリ秒です。すなわち、200秒周期でrunメソッドの内部が実行されるわけです。
Treadを使った場合は、runの中で無限ループを記述して終了条件を外部に持たせるかと思いますが、ScheduledExecutorService の場合はshutdownメソッドを使うだけですみます。
後はこのスレッドはキャラクターの移動などの処理を行い、再描画をかければOKです。非常に簡単ですね。

ソース全体はこちらからどうぞ。