「Galaxy Tab」でチップセット画像が崩れる際の対応方法 - 「Ex Reversi」を「Galaxy Tab」に対応させた時のメモ


2011/01/23 ページ作成
クロノス・クラウン合資会社
柳井政和
HP:http://crocro.com/
Twitter:http://twitter.com/ruten

はじめに

Android版の「Ex Reversi」は、2009年の4月にリリースしたアプリケーションです。

この「Ex Reversi」は、変形盤面を指すことができるアルゴリズムを搭載しています。このアルゴリズムは「n次元の変形盤面リバーシ」を指すためのアルゴリズムとして、2000年に柳井政和によって考案されました。このアルゴリズムを、高速化のために2次元に限定してJAVAに実装したのが「Ex Reversi」のエンジン部分になります。

このAndroid版の「Ex Reversi」ですが、ちょうどAndroid 1.5の頃に開発され、その後何度かのバージョンアップを重ねてきました。今回、Android 2.3の「ADK」に、「Galaxy Tab」の「AVD」が同梱されていたので、対応させることにしました。

結論から言うと、そのまますんなりとは動きませんでした。1.5の頃に書いたプログラムということもあり、現状の環境を想定していなかった部分もあり、予想外の動きをしました。そこで本稿では、発生した問題と、行なった対処をまとめておきます。

同じような問題に遭遇した人の一助になればと思います。

「Galaxy Tab」への対応1

まず、プログラムを「Galaxy Tab」に対応させるために、「AndroidManifest.xml」の設定を変更しました。

「Ex Reversi」は、Androidの1.5以降を対象にしていました。そのため、「AndroidManifest.xml」の「minSdkVersion」を「3」に設定していました。この場合、「Galaxy Tab」で、画面は表示されますが、「320×480」という小さなサイズで表示され、かつその周囲に余白が出てしまいます。結果として、何も表示されない黒い領域が、画面に多く残ってしまいます。

これは、1.5の設定では、画面サイズが対応していないためです。

そこで、まずは「minSdkVersion」を「4」にしました。すると、画面いっぱいにアプリケーションの描画が行なわれるようになりました。しかし、ここで問題が発生しました。

画像のうち、チップセットとして用意していた画像の表示が「崩れる」(正しく表示されない)という問題が発生したのです。

発生した問題の原因

原因は2つありました。

原因1

1つ目の原因は「BitmapFactory.decodeResource(Resources res, int id)」というメソッドを使うと、画像をリソースから読み込む際に、自動で画像がリサイズされてしまうことです。

マップ画面などによく使われるチップセット用の画像は、複数の画像を1枚の画像としてまとめています。そして、画像の読み込み位置と、切り取り位置を指定して、切り貼りしながら、画面に画像を描画します。

このチップセットのサイズが自動でリサイズされると、参照位置がおかしくなり、かつ切り取り範囲も誤った場所になります。この結果として、画像が「崩れて」しまいます。

原因2

2つ目の原因は、「canvas.drawBitmap(Bitmap bitmap, float left, float top, Paint paint)」メソッドで画像を描画する際に、画像が自動でリサイズされて描画されることです。

このため、例えば「40ドット×40ドット」のサイズとして作成した画像を画面に描画すると、「60ドット×60ドット」の範囲に拡大されて描画されてしまいます(「Galaxy Tab」では1.5倍にリサイズされていました)。

この問題は、画像をタイル状に敷き詰める処理を行う際に問題になります。40×40の画像を画面上に敷き詰めたつもりが、自動で60×60に拡大されて描画されてしまうので、意図しない表示結果になってしまいます。

解説

このような、画像の自動リサイズは、通常のアプリケーションでは便利な機能かもしれませんが、ゲームでは逆に問題を引き起こします。

以下、この2つの問題を解決する方法を書きます。

「Galaxy Tab」の画像読み込みへの対応

画像を、自動でリサイズすることなく読み込むには、以下のようなプログラムを書きます。

BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inScaled = false;
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.hoge, opt);

「BitmapFactory.Options」を使い、「inScaled」フラグに「false」を設定して、「decodeResource()」の引数に設定すれば、リサイズを行なわずに画像を読み込むことができます。

「Galaxy Tab」の画像描画への対応

「canvas.drawBitmap(Bitmap bitmap, float left, float top, Paint paint)」メソッドは、デバイスによっては、画像をリサイズして描画します。このリサイズ機能を使わずに描画を行なうには、画像の描画サイズを明示的に指定するとよいです。以下、その方法をコードで示します。

まずは、メソッド外の変数を示します。

Rect  mRctSrc  = new Rect();
RectF mRctFDst = new RectF();

次に、メソッド内の変数を示します。

int w = mBitmap.getWidth();
int h = mBitmap.getHeight();
mRctSrc.set(0, 0, w, h);
mRctFDst.set(x, y, x + w, y + h);
canvas.drawBitmap(mBitmap, mRctSrc, mRctFDst, mPaint);

また、リサイズされたサイズを取得したい場合は、以下の方法で取得できます。

int sW = mBmp.getScaledWidth(canvas);
int sH = mBmp.getScaledheight(canvas);

まとめ

通常の画面サイズのデバイスでも「Galaxy Tab」でも、「BitmapFactory.Options()」の「inScaled」は「true」になっています。しかし、通常の画面サイズでは画面のリサイズは行なわれませんが、そうでないデバイスでは画像がリサイズされます。

今回、「Ex Reversi」は、古いプログラムだったために、こういった画面サイズが考慮されていませんでした。

(Androidの仕様としては前からあったけど、デバッグ環境がなかったので見落とされていた)

同じようなケースで引っ掛かる人は、それほど多くはないとは思いますが、何かの参考になるかもしれないので、情報をまとめておきます。

Cronus Crown(クロノス・クラウン)のトップページに戻る
(c)2002-2017 Cronus Crown (c)1997-2017 Masakazu Yanai
このWebPageに関するご意見・お問い合わせは
サイト情報 弊社への連絡
までお願いします。