1次元配列でも大丈夫
この手の格子マップものを作る場合、マップ管理には1次元配列を使うようにしています。
1繋がりの配列をマップ横幅のマス数毎に区切って、列が変わるものとして扱うわけです。
0,0 | 1,0 | 2,0 | 3,0 | 4,0 |
0,1 | 1,1 | 2,1 | 3,1 | 4,1 |
0,2 | 1,2 | 2,2 | 3,2 | 4,2 |
0,3 | 1,3 | 2,3 | 3,3 | 4,3 |
0,4 | 1,4 | 2,4 | 3,4 | 4,4 |
↓
000 | 001 | 002 | 003 | 004 |
005 | 006 | 007 | 008 | 009 |
010 | 011 | 012 | 013 | 014 |
015 | 016 | 017 | 018 | 019 |
020 | 021 | 022 | 023 | 024 |
(DropsDealerは2次元マップにドロップを置いていますが、位置情報は1軸で扱うようにしていました。
更に、既存の落ち物との違いを出すために1軸の連続性をドロップの動きにも反映させています。)
位置の指定は1軸だけにします。X,Yの2軸ではなく1つの情報で表すため、自ずとサイズ削減になります。
スクリプト的には、配列アクセス時にmap(x,y)→map(pos)と引数を減らせるのはもちろんですが、
そのほかの判定や計算などでx、yの2軸を扱わなくなること自体がかなりサイズ削減に有効です。
kacotte!では斜め方向のマスは見ていませんが、右上のマスの情報が必要ということであれば、
2軸だとmap(x+1,y-1)のような指定になるところ、1次元ではマップ横幅21なら map(pos-20) にアクセス
すればよいことになり、何カ所もあると相当のコスト(バイト数)を削減できます。
ただし、画面描画にはxyの指定となるため、位置情報を画面座標に変換する処理は必要になります。
実スクリプトでは、こんな書き方。(マップ横幅21マス、1マスの画像は32×32ピクセル)
eex+=((eep\21*32)-eex)/eeq eey+=((eep/21*32)-eey)/eeq
eepが目的地となるマスの位置情報、eex,eeyが描画用画面座標(画面上の現在位置としても保持)。
eeqは、現在位置から目的地までの移動まであと何フレームかを示す移動カウンタ。移動開始時に設定。
これらの変数の実体はオブジェクト管理テーブル上にあり、使うときにdupしています。
ちなみに、このコードでは、現在の画面座標変数の値と、eepから求められる画面座標の差分をとり、
それをeeqで割った値を元の画面座標の変数に加算、ということをしています。
eeq=1の場合、eex,eeyがどんな値でも、eepで指定したマスに対応する画面座標になります。
実際のオブジェクトの移動処理では、移動開始時に、eepに行先の位置情報、eeqに所要フレーム数を
設定し、eeq>0ならこのコードで描画用画面座標を更新、eepを1減算という流れで処理します。
移動で更新される都度、差分とeeqが減っていき、eeqで割った値は毎回だいたい同じになります。
eeqを1減算して0になった場合は目的地に到着していますので、方向転換などの処理を行います。
2軸管理でもこの移動カウンタ処理は使いますし、共通ルーチン一か所ですませられるため、
位置情報→画面座標の変換をついでに行うのは大したコスト増ではありません。