ニンジャのゲームを作る - ②マス目式マップの内部
Unityに3Dモデルを移送する
前回作成したモデルを、Unity上にインポート(読み込み)しました。ところでUnityとは? ゲーム製作に使われる非常に強力な総合ツールです。これを使うだけで、広範囲にわたる知識が必要な3D描画や物理演算といった難しい技術も、1度作ってさえしまえばWindowsやMac、iOSにAndroidといった複数プラットフォーム(端末)への対応も、(比較的)楽に取り入れることが可能になります。
マス目マップを数字で表す
さて、ここからがゲーム本体を作るもっとも大切な作業です。作るものは山積みですが、何事もまずはしっかり足場から。ヤモト=サンが移動するためのマップを作っていくことにします。
今回作るゲームのマップは、ゲーマーの方にはお馴染みのマス目式です。ご存知ない方は、将棋盤を思い浮かべていただければ分かりやすいと思います。
このように等間隔に並んだマスの上を、将棋のコマの代わりにキャラクターが移動するのが、マス目式のマップです。
では、このマップをどうやって作ればいいのでしょうか? Unity上で何かを作るためには、だいたいプログラミングが必要となってきます。横文字で書くと何やら難しそうですが、要はコンピューターにも理解できる『指示書』を作る作業です。順を追って考えていきましょう。
まず、この将棋盤をプログラム上で再現する方法を考えていきましょう。この盤には横に9個のマスがあり、縦にも9個のマスが並んでいます。単純に数字に直せば、9桁の数字を9つ並べれば、同じ内容を表せることが分かります。
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
縦に長くなってしまいましたが、この仮想将棋盤と先ほどの将棋盤、表しているものは同じです。数字に直すことで、コンピューターの扱いやすい形で将棋盤を表すことが可能になります。この理屈を使ってマップを作っていくのです。
例えば、『四方を壁に囲まれた部屋』のマップを考えてみましょう。先ほどの将棋盤と違い、部屋には壁と床、2種類の要素が存在します。まずは分かりやすくするため、漢字で表してみましょう。
壁壁壁壁壁壁壁壁壁
壁床床床床床床床壁
壁床床床床床床床壁
壁床床床床床床床壁
壁壁壁壁壁壁壁壁壁
続いて、これを数字へ変換します。2種類の要素があるため、今回は0に加え、1も使いましょう。床が0、壁が1です。
111111111
100000001
100000001
100000001
111111111
これをプログラム上に入力すれば、内部のマップデータは完成します。
1つのマップを2つのマップで表す
しかし、少し待ってください。0と1でマップを構成したわけですが、これには1つ肝心なものが欠けています。ヤモト=サンです。現在は3Dモデルとして別個に表示されてはいますが、今後ゲームを作っていく以上、彼女もマップデータ上に存在させる必要が出てきます。
彼女の存在をどうプログラムしましょうか。0、1と来たから2をヤモト=サンとして表現するというのも一つの案ですが、それでは一つ困ったことが起こります。
例えば、床の種類を「毒の床」「氷の床」「トラップ床」と3種類に増やしたとしましょう。これにそれぞれヤモト=サンが乗っている場合と乗っていない場合を表すとき、数字はいくつ必要となるでしょうか?
答えは「3の2乗」。つまりは9個です。これに通常の床、壁、ヤモト=サンの表現に足し合わせれば、それだけで12個です。1桁ではもう足りません。
「16進数」という0〜9の数字とA~Fの英字を使うことで0〜16を表す記法もあるのですが、これもかなりギリギリですし、床の種類を追加すると一瞬で溢れます。床の種類を限定してしまえば、これでも済むのですが、やはりこれから製作していく以上、拡張性は確保しておきたいものです。
ではどうするかというと、マップをもう1つ、別に作成します。こちらでヤモト=サンなど、キャラクターや宝箱の位置を表せば、桁が溢れる心配を大きく減らすことができます。
2つのマップを作り上げれば、今度こそマップの内部データは完成です。これでヤモト=サンは舞台の上に……
立っていませんでした。内部でマップができても、それを表示に反映するプログラムは作られていないからです。次はこの内部マップを用い、空間にマップを現出させていきましょう。
マップデータから実際のマップを作る
内部において、マップはすでに出来上がっています。なら話は簡単です。壁と床の表示用モデルを用意し、マップの通りに並べていけばいいのです。
Unityには「プレハブ」といって、データをひとまとめにしたものを登録し、複製を作れる機能が付いています。早速、くだんの壁、床の3Dモデルをプレハブとして登録し、並べていきましょう。
自動化された操作は、コンピューターの真骨頂。プログラムさえしてしまえば、作業はほぼ一瞬で終了し……
こちらのマップが出来上がりました。これでようやく完成……と言いたいところですが……
左に向かって歩かせてみると、ヤモト=サンが壁の中に入ってしまいました。まあ当然といえば当然です。「0」と「1」が「床」と「壁」を表すことは教えましたが、ヤモト=サンは壁をすり抜けられないという事実は、まだプログラムされていないのです。
めげずに続けていきましょう。すり抜けられないという現象を実現させるには、壁に当たり判定をつけたり……するのもいいのですが、今回はもっと単純に、壁に向かっての移動をキャンセルする方法で進めていきます。
つまり、移動する前に「そこは壁かどうか」を判定し、壁であれば移動を打ち切ってしまえば良いのです。
壁かどうかの判定は……前述の通りです。「1」であれば壁。現在、ゲームの内部には、こちらの数字で構成されたマス目マップと……
111111111
100000001
100000001
100000001
111111111
中央にヤモト=サンが存在する、キャラ配置マップが存在します。
000000000
000000000
000010000
000000000
000000000
表示上の移動は、3Dモデルのヤモト=サンを、マス目の大きさぶん動かせば完了します。内部の移動は、移動先の数字を「1」に置き換え、移動元の数字を「0」に置き換えることで完了です。
この動作の前にチェックを加えましょう。例えば、このような状態の時……
111111111
100000001
100000001
100000001
111111111
↑マス目マップ(壁と床配置) キャラ配置マップ↓
000000000
000000000
010000000
000000000
000000000
ここで上下右へ動いても移動先は0(床)なので問題ありませんが、左の移動先は1(壁)です。ここに移動させると、2つのマップ上の壁とキャラの配置が重なり、結果として壁の中に埋まってしまいます。
なので、移動前にキャラ配置マップのヤモト=サンの位置を取得し、続いてマス目マップ上の移動先の数値を調べます。それが1であれば移動はキャンセルです。これをプログラムすれば……
この状況下で左へ移動させようとしても出来なくなりました。ゲーム上に壁が出現したのです。実際には床と壁にデータ上の違いはないのですが、壁を表現することはできました。
マップの内部のお話はここでおしまいです。次回は今回のゲームに必要不可欠な「マップの生成」についてのお話をしたいと思います。
それは誇りとなり、乾いた大地に穴を穿ち、泉に創作エネルギーとかが湧く……そんな言い伝えがあります。