Androidでゲーム作成(2)
昨日に引き続きAndroidでゲームを作るパターンを紹介します。
ゲームを作成する場合、なんらかのタイミングで画面を再描画していきますが、イベント駆動で再描画するパターンと一定周期で再描画するパターンの2つがあります。先に紹介したパターンはイベント駆動型で、キー入力をイベントに反応して再描画していました。これはカードゲームやシミュレーションゲームの場合には有効です。しかし、アクションゲームやシューティングゲームでは一定周期で再描画しなくてはなりません。そのような場合、描画用のメインループを作成するなどして、定期的な描画を行います。
メインループをどうやって実装するか?
メインループの実装方法は幾つかありますが、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です。非常に簡単ですね。
ソース全体はこちらからどうぞ。