2011年12月6日火曜日

「androidで動くゲームプログラミング入門」 その3

「androidで動くゲームプログラミング入門」 その2の続きです。

[複数の解像度への対応]
Androidは色々な解像度の端末に対応できるように作られています。その機能を活かすには、Android.xmlのmanifestに以下のように書きます。

  <supports-screens
     android:smallScreens="true"
     android:normalScreens="true"
     android:largeScreens="true"
     android:xlargeScreens="true"
     android:anyDensity="true"/>

この説明はyanzmさんのblogに詳しく書いてあります。

ここでは画像データの対応について書きます。画像データはres/drawableの下に置くのですが、解像度と画面密度別に複数のデータを置けるようにできています。
画面サイズはsmall,normal,large,xlargeの4種類。
画面密度はldpi,mdpi,hdpi,xhdpiの4種類あります。このうちxlargeとxhdpiはandroid 2.3以降の対応になります。
携帯端末では480x320はmdpi、8??x480はhdpi、1280x720はxhdpiになるはずです。
drawable-hdpiに800x480向けの画像データを入れておくと読み込んだ時に、mdpi端末では縮小され、xhdpiでは拡大され、ちょっとボケますが拡大縮小などせずにそのまま使えます。
ここでちょっと落とし穴があって、拡大/縮小の具合は画面密度でされるのです。解像度ではありません。自分は勘違いしていて解像度に合わせて拡大/縮小してくれるのだと思っていました。だからタブレット端末だと画像を拡大してくれるのかと思っていたのです。とろこがタブレット端末は高解像度(1280x768ぐらい)ですが、画面密度は中程度なのです。ですからmdpi扱い、つまり縮小されてしまいました。画面が大きくなって画像が縮小されてしまって、小さい画像が表示されて困ってしまいました。解決方法はAndroidディベロッパーラボ東京の時に教えていただきました。
解決方法はタブレット端末の画像は drawable-xlarge-mdpi に入れるでした。1280x768用のデータを作りdrawable-xlarge-mdpiに置き無事解決。
言語毎にデータを分けることもできます。
データを置くディレクトリ名のルールは drawable-言語-解像度-画面密度 となります。
これはlayoutでも同様で layout-言語-解像度-画面密度となります。(試していません、間違っていたらごめんなさい)

例えば、現在売られている端末に合わせて画像データを作るとします。画像制作の手間を減らしたいのでなるべく種類は少なくします。解像度が低い端末向けには用意しません。androidによって縮小された画像を使うようにします。画像の縮小なら劣化はあまり目立ちません、ただしOut of memoryには注意です。目立つのは画像の拡大ですので大きな画像を用意します。
800x480(携帯)向け、1280x768(タブレット)向け、1280x720(携帯向け)。このうち1280x720と1280x768は同じデータで済めば楽だと思います。

ディレクトリ構成は以下のようになります。
drawable-hdpi  (800x480) 各言語共通
drawable-xhdpi (1280x720) 各言語共通
drawable-xlarge-mdpi (1280x768) 各言語共通
drawable-ja-hdpi  (800x480) 日本語用
drawable-ja-xhdpi (1280x720) 日本語用
drawable-ja-xlarge-mdpi (1280x768) 日本語用

例えばこのように動作します。800x480の端末で言語を日本語にすると drawable-ja-hdpi 以下のデータが読み込まれ、もしなければdrawable-hdpiのデータが読み込まれます。
言語設定が日本語以外ならdrawable-hdpi以下のデータが読み込まれます。
このように作るとandroidの「画面サイズが違っても表示される大きさは同じ」という考えと合いません。「高解像度の端末だと大きく表示される」になります。ゲームは絵が大きい方が見やすいですし、楽しいですから。
実際にこのように作ったのがこれです。よかったらダウンロードして遊んでみてください。タブレットでも画像がボケずに大きく綺麗になっています。

[まだ作っていないところ]
今回作ったのはサンプル的なもので、実装レベルもまだまだです。たとえばセーブ機能がありません。プログラムの状態が保存できないので端末の向きを変えるとゲームは最初からやり直しになります。端末を回転させると、ActivityのonDestory()が呼ばれ、onCreate()からやり直しだからです。そうならない為にはセーブしておかなければなりませんが、実装していません。セーブはonPause()で行うのが基本です。
ゲームの基本的な動きは作ったつもりですが、商品レベルにするにはまだまだ沢山作りこまなくてはなりません。UIをまともに作っていないのでちゃんと作る。見た目を格好良くする。ランキングシステムはどうする。広告はいれる? などなど。

コードの説明は androidに関連する部分だけにしてゲーム部分の説明はしませんでした。たぶん読んでも眠くなるだけですし。
質問、コメントや間違いの指摘を寄せていただいたら有難いです。

「androidで動くゲームプログラミング入門」 その1
「androidで動くゲームプログラミング入門」 その2
「androidで動くゲームプログラミング入門」 その3

0 件のコメント:

コメントを投稿