This document written: 2014-05-19 .. 2014-05-30

『Android ゲームプログラミング A to Z』実装に使う Android API 群(前編)

前章ではゲームプログラムで必要となる機能(ドライバー的なものが中心だった)について概観したので、それらを実装するために使うことのできる Android の API について拾い出していくのが本書(BAG)の第 4 章である。原著が Android の 2.x 全盛期に著されたもののため、Android API についてはやや古い環境が主眼とされている感じもあるので、そのあたりは最新の情報と照合しつつ、見ていきたいと思う。

AndroidManifest.xml

manifest

installLocationpreferExternal を指定するのが(比較的容量の大きくなる)ゲームアプリでは普通だろう。

activity

画面方向の固定(screenOrientation の指定)、設定変更時の AndroidOS による Activity の再起動の抑制(configChangeskeyboard | keyboardHidden | orientation を指定する)。

uses-permission

起動ロック(WAKE_LOCK)、外部 SD の読み書き(WRITE_EXTERNAL_STORAGE)など。

※ Android 4.4 (KitKat) では WRITE_EXTERNAL_STORAGE を指定せずとも、外部 SD の当アプリ専用ディレクトリの読み書きは可能である。つまり次のようにしておけばよい:


<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>

uses-feature

特定のハードウェア機能を必須とする場合は指定する。マルチタッチならば multitouch.distinct。OpenGL ES 2.0 以上ならば glEsVersion に 0x00020000 を指定するなど。

ライフサイクル

Android にはライフライサイクルが細分化されて onXXX 系のメソッドが多種用意されているものの、これは全部使い分けるべきというわけでは決してない。あくまでも様々な状況を想定してとりあえず用意されているわけであって、実際のアプリケーションの実行状況(ユースケース)においては、ほとんどが不要で、必要なものは限られている。BAG におけるゲーム用フレームワークでは、onCreate()onPause()onResume() の 3 つで十分であるという結論が述べられている。すなわち、onCreate() で初期化、onResume() でメインループの開始と、アプリ中断からの復帰時においては待避したデータの復元、onPause() でメインループの停止と、isFinishing() 時にはさらにアプリ中断によるデータの待避、ということである。

タッチ(入力)

入力デバイスについて、キーボードや加速度センサーはざっくり割愛する。

原著の執筆時期がちょうどマルチタッチ性能について急激に充実した時期と重なるため、シングルタッチ対応とマルチタッチ対応の両方を考慮することを前提に説明されている。Android 2.3 以降においては、マルチタッチを前提として構わないので、現時点ではもうこちらだけを考慮すればよい。

シングルタッチの場合はさほどでもないが、マルチタッチの場合は、ポインター ID を取得する必要があり、ポインター ID を取得するには「ポインター ID」が格納されているリストの「ポインター Index」が必要になるので、少々混乱してわかり辛いというようなことが BAG では説明されている。さらに、API のメソッド名も Android 2.3 未満と以降で変更されたので余計にややこしいという解説がされているが、今では 2.3 以降の改善されたメソッド名の使用のみを考慮すればいいので、以前ほど大変ではない。

API としては View.OnTouchListener を使うと言えば簡単そうだが、むしろこの OnTouchListener によって渡される MotionEvent オブジェクトの扱いが(マルチタッチの場合は)複雑である。

ファイル(入出力)

asset は AssetManager オブジェクトから InputStream オブジェクトを得る。InputStream の扱いは Java 一般の話題となる。

外部 SD は Environment.getExternalStorageDirectory() で File オブジェクトを取得できると BAG には書いてあるが、これはやや古いやり方で、新しい Android では Context の getExternalFilesDir() メソッド が推奨される(こちらのメソッドを使うと、API-19 ではさらに WRITE_EXTERNAL_STORAGE パーミッションが不要となるという特典もある)。また、こちらの方式ではアプリのアンインストール時には自動的に削除して後片付けしてくれる。

逆に、アプリのアンインストールによってデータが削除されないようにするには、Environment.getExternalStorageDirectory() を使った方がいいともいえる。

そして、外部 SD は常に利用できるとは限らず、USB ケーブルで PC と接続した場合は一時的に使えない場合もある。そのために確認を行いたい場合は Environment.getExternalStorageState() を使う。

取得した File オブジェクトの扱いに関しては、Java 一般の話となる(BufferedReader / BufferedWriter を使う等)。

音(出力)

効果音(SE) は SoundPool クラスを、音楽(BGM)は MediaPlayer クラスを使う。

また、SoundPool オブジェクトや MediaPlayer オブジェクト自体の音量指定とは別に、ボリュームボタンよるボリューム調整を有効にするためには Context に対して setVolumeControlStream メソッドで STREAM_MUSIC をセットする必要がある。

グラフィックス(出力)

残るグラフィックス関連は中編に続く……


読解『A to Z』