携帯ゲームで人気のジャンルに、(2D)RPGがあります。いわゆるドラクエ風の地形チップ画像を敷き詰めたマップを移動しながらコマンド選択で敵と戦うゲームですね。

iアプリライブラリ(DoJa)には、このマップ表示を簡単に実現できるImageMapというクラスが用意されています。今回は、このImageMapで「大きなマップ画面の一部をスクロール表示する」テストプログラムを作ってみましょう。

ImageMapの仕組みは、複数のチップ画像とマップデータを登録しておいて、その「一部」をGraphicsオブジェクトのdrawImageMap()で指定位置に描画する、というものです。具体的には、適当な大きさのチップ画像の配列と、マップ情報としてその地形チップの番号(配列インデックス)を並べた配列を用意し、「チップ画像のサイズ」「マップ全体のサイズ(縦横のチップ数)」と一緒にコンストラクタに渡してImageMapを作成します。

たとえば、個々のチップ画像の大きさをCHIP_WIDTHピクセル×CHIP_HEIGHTピクセルとし、マップ全体をMAP_COLS×MAP_ROWSチップで構成、マップデータをmap、チップ画像の配列をchipとするのなら、以下のようにしてImageMapオブジェクトを作成するわけです。

// ImageMap作成
imap = new ImageMap(CHIP_WIDTH, CHIP_HEIGHT, MAP_COLS, MAP_ROWS, map, chip);

マップデータmapは、MAP_COLS×MAP_ROWSチップ分の配置情報を保持するbyte型配列です(DoJa4.0以降では、int型とするコンストラクタもあります)。一次元配列なので、マップの(x, y)の位置に配置するチップ画像の番号をmap[x + y * MAP_COLS]に書き込んでおきます。

こうして作成したImageMapは、setWindowで可視範囲を指定し、描画したいGraphicsのdrawImageMap()メソッドで渡すことで、「マップの指定された範囲にあるチップ画像」が描画されます。

ただし、setWindow()で指定できるのは、チップ単位の位置ですので、注意してください。ゲームのフィールド表示などでスクロールしながら表示したい場合は、自分で「描画位置をずらしながらスクロール表示」する必要があります。

テストプログラムでは、20*20ピクセルのチップ画像を11*11チップ並べて表示するようにしてみました。実行すると、自動的に右スクロールしていきます。

スクロール表示では、「実際に見える」大きさ(11*11チップ)よりスクロールで新たに見えてくる横1チップ分だけ広い12*11チップの可視範囲を設定したImageMapを、描画用のImageに描いてから画面に表示しています。
スクロール中は、ImageMapの表示開始X座標をImageの範囲外となるマイナス方向に「引っ張って」いくことで、右側の部分を表示される領域に持ってくるようにしてみました。

可視範囲の設定をピクセル単位で行えれば、わざわざ「実際に表示される領域」のために別にImageを用意するなどの手間もなくなってより便利になるんですけどね。ただ、「マップ全体を(仮想的に)描画した全体画像」として利用できるので、すべて自分で実装するのに比べれば楽ですし、システム側にこうした機能を用意することで性能的にも向上させやすくなるのが利点でしょうか。

プログラムソース表示


創作プログラミングの街 > 携帯iアプリ開発実験室