[Javascript] ゲームの座標データ回転に使える、2次元Arrayデータの縦横をpivot変換する方法

ちょっとしたゲームを作る時に、データ保存している配列データを変換させるケースが多いです。 今回はとあるデータマップが2次元配列で登録されていて、それを回転させる時の処理サンプルを備忘録しておきます。

Case

次のようなビットマップにも使えるようなマップデータを2次元配列で作っているようなケースが該当です。 [ [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,1,1,1,1], ] このマトリクスをテーブル上で1の部分を黒色で表示すると、Lの文字が表示されます。 このアイテムを、クリックした際に、90度ずつ回転させるテトリスの様な操作をする場合に、どのようにデータマップを変換すればいいのか?というケースです。

Source Code

arrays_pivot.js

変換する処理を1つの関数で書きました。 function arrays_pivot(base_data , rotate){ rotate = rotate || 0 const new_data = [] switch(rotate){ case 90: for(let i=base_data.length-1; i>=0; i--){ for(let j=0; j<base_data[i].length; j++){ new_data[j] = new_data[j] || [] new_data[j].push(base_data[i][j]) } } return new_data case 180: for(let i=base_data.length-1; i>=0; i--){ for(let j=base_data[i].length-1; j>=0; j--){ new_data[base_data.length-1 - i] = new_data[base_data.length-1 - i] || [] new_data[base_data.length-1 - i].push(base_data[i][j]) } } return new_data case 270: for(let i=base_data.length-1; i>=0; i--){ for(let j=base_data[i].length-1; j>=0; j--){ new_data[base_data[i].length-1 - j] = new_data[base_data[i].length-1 - j] || [] new_data[base_data[i].length-1 - j].unshift(base_data[i][j]) } } return new_data default: return base_data } }

index.html

HTMLで次のように書くと、データ変換ができます。 <script src='arrays_pivot.js'></script> <script> const base_data = [ [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,1,1,1,1], ] console.log( arrays_pivot(base_data,0), arrays_pivot(base_data,90), arrays_pivot(base_data,180), arrays_pivot(base_data,270) ) </script>

Response

上記コードを実行した時のレスポンスです。 # 回転: 0 [ [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1, 1, 1, 1, 1] ] # 回転: 90 [ [1, 1, 1, 1, 1] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] ] # 回転: 180 [ [1, 1, 1, 1, 1] [0, 0, 0, 0, 1] [0, 0, 0, 0, 1] [0, 0, 0, 0, 1] [0, 0, 0, 0, 1] ] # 回転: 270 [ [0, 0, 0, 0, 1] [0, 0, 0, 0, 1] [0, 0, 0, 0, 1] [0, 0, 0, 0, 1] ] おわかりいただけただろうか? ビットマップデータが90度単位で回転していて、この関数を利用して、オブジェクトの回転データを変換取得することができました。

解説

arrays_pivot関数には、元データとその回転値を送ることで、簡単に変換後の配列データを受け取れます。 回転値が送られなかった場合は、そのままのデータを返しています。 このマップデータは、2次元目のデータの要素数が全て同じであることが条件になっていて、長方形データでも対応できるようになっています。 関数の中では、x軸とy軸を入れ替えて縦横データの入れ替えと、回転をした時のデータが逆になる特性から、for文を0スタートと逆値のスタートでそれぞれ処理しています。

あとがき

この処理、ゲームをやっている時に、これまで何度も書いてきた処理なんですよね。 こうして備忘録を残しておくことで、今後自分の役に立つこと間違いないです。 そして、もっとスマートな書き方に変えていって秀逸な関数にしたいですね。 データも、今回は2次元配列データでしたが、文字列のビット構造にしてもっと物理バイトを軽くするという手段もあるので、確実に今後バージョンアップされていくでしょうね。 個人的にこうした部分処理を作るのは非常に楽しいと感じてしまった、今日のブログでした。