穴掘り法で2D迷路を作る
前回、前々回と見下ろし2Dマップ上でプレイヤーを動かすことが出来ました。
今まではマップデータを自分で作ってマップを作成していましたが、今回は穴掘り法と呼ばれる方法を使って自動でマップを作ってみたいと思います。
この記事はシリーズものとなっています。
穴掘り法
穴掘り法とは
迷路を生成するアルゴリズムは棒倒し法、棒伸ばし法など複数ありますが、穴掘り法はその名の通り、穴を掘って迷路を作っていくという方法です。
まず外側の外周を通路にして、それ以外を壁で埋め尽くします。
次にランダムでスタート地点を選び、そこから伸ばせる限り穴を掘って道を伸ばしていく感じです。
具体的には上下左右の二マス先を調べ、道がなければ掘ると言った感じです。
道が伸ばせなくなったらすでに掘った道のいずれかを起点にして同じ手法で穴を掘って道を伸ばしていきます。
これを繰り返し、全ての道が掘れなくなった時点で外周を壁で埋め、迷路は完成します。
箇条書きにするとこんな感じでしょうか。
- 外周以外を壁で埋め尽くす
- スタート地点から伸ばせる限り道を伸ばす
- 上下左右2マス先が全て道になれば別の起点から掘る
- 全ての道が掘れなくなった時点で外周を壁で埋める
穴掘り法プログラミング
それでは実際にプログラミングしてみましょう。
今回はこちらの記事を参考に作ってみたいと思います。
それではUnityのAssetsフォルダにMazeCreatorというC#スクリプトを作成します。
変数や定数の定義
必要な変数や定数などを定義しましょう。
内容に関してはコメントの通りです。
Cellクラスは後々起点を保持しておくために使います。
一点注意ですが、迷路生成に関してはUnityEngineを使いませんので、MonoBehaviourは継承していません。
このMazeCreatorクラスはゲーム開始時に別のクラスから呼ばれ生成されます。
コンストラクタ作成
ではMazeCreatorのコンストラクタを作成していきます。
このような感じです。
今回の迷路では幅が5以上、そして縦も横も奇数のマス目にします。
どこの通路にもつながらない閉じた領域が出来るのを防ぎ、ぐるぐるループする迷路が出来ることを防ぐためです。
迷路作成関数
次に迷路を作成するために必要な関数を定義します。
必要な関数は4つです。
- 迷路データを作成する関数
- 掘る道を決める関数
- 道を彫り次の起点候補を決める関数
- 起点位置をランダムで選択する関数
このように関数を定義します。
ではCreateMazeを作っていきます。
続いて穴を掘っていきましょう。
Dig関数はこのようになります。
少し長いですが処理の流れはコメントの通りです。箇条書きにすると、
- 乱数生成用の変数を作成
- ループ突入
- 方角保持用リスト作成
- 上下左右2マス先までが壁かどうか判別
- 壁ならば方角保持用リストに方角追加
- 方角が0ならループ終わり
- 終わらないなら_x座標、_y座標に道と起点をセット
- 掘る方角をランダムで取得
- 取得した方角に掘り進める
- 次の起点を取得
- 起点が有るなら新たな起点から掘る
でしょうか。
全体が完成したら理解出来るかと思いますので、後で見返してください。
続いて道をセットし次の起点候補を保持する処理、SetPathを作ります。
こちらは至ってシンプルです。
起点となる座標は奇数にしておかないときれいな迷路にはなりませんのでご注意ください。
最後に新たな起点を選ぶ関数を作成します。
これで穴掘り法で迷路を作成するプログラムが出来上がりました。
全体も載せておきます。
生成したマップをゲームで表示する
これで2Dマップをランダムで作る準備が出来ました。
いよいよゲーム画面に迷路を表示させてみます。
マップデータを表示
前回作ったMapGeneratorの_loadMapData関数に処理をくわえていきます。
このような感じになります。
実際に起動してみるとこのように迷路がランダムで生成されています。
プレイヤーを表示させる
この状態ですとMAP_TYPEのPlayerが登場しませんので、1,1の座標にプレイヤーを表示させてみましょう。
修正箇所はMapGeneratorの_createMap関数内、マップタイルをループで生成していく箇所です。
このようになります。
実行してみるとちゃんと1,1の座標にプレイヤーが表示され、迷路内を移動させることができました。
コードが長く、難しいところも有るかと思いますが、流れを確認して読んでみるとご理解頂けるかと思います。
また今回の記事は以前の記事の続きとなっています。
前回、前々回の記事を読まれていない方は是非、読んでみてください。
Unity開発おすすめPC
NEXTGEAR JG-A5G5A

CPU : AMD Ryzen™ 5 4500 プロセッサー
グラフィックス : NVIDIA® GeForce RTX™ 3050
メモリ標準容量 : 16GB (8GB×2 / デュアルチャネル)
M.2 SSD : 1TB (NVMe)
保証期間 : 3年間センドバック修理保証・24時間×365日電話サポート
Lenovo LOQ Essential Gen 9 - ルナグレー

CPU : インテル® Core™ i7-12650HX
グラフィックス : NVIDIA® GeForce RTX™ 4050 Laptop GPU 6GB GDDR6
メモリ標準容量 : 16 GB DDR5-4800MHz
ストレージ : 512 GB SSD M.2 2242 PCIe-NVMe Gen4 QLC
ディスプレイ :15.6" FHD液晶 (1920 x 1080) IPS, 光沢なし, マルチタッチ非対応, 100%sRGB, 300 nit, 144Hz
内蔵カメラ :720p HDカメラ (プライバシーシャッター付)
無線 :Wi-Fi 6対応 (IEEE 802.11ax/ac/a/b/g/n準拠) 2x2 & Bluetooth®
保証期間 : 1 年間 Legion Ultimate Support
【MDT46T144】

グラフィックス : RTX 4060 Ti
メモリ標準容量 : 16GB
ストレージ :500GB
保証期間 : 通常1年保証(無償1年)
LOQ Tower 17IRR9 :カスタマイズモデル

CPU : インテル® Core™ i5-14400F プロセッサー
グラフィックス : NVIDIA® GeForce RTX™ 3050 6GB GDDR6
メモリ標準容量 : 16 GB DDR5-4800MHz (UDIMM) - (2 x 8 GB)
ストレージ : 512 GB SSD M.2 2280 PCIe-NVMe Gen4 TLC
保証期間 : 1 年間 Legion Ultimate Support
NEXTGEAR JG-A5G60(ホワイトカラーモデル)

CPU : AMD Ryzen™ 5 4500 プロセッサー
グラフィックス : NVIDIA® GeForce RTX™ 4060
メモリ標準容量 : 16GB (8GB×2 / デュアルチャネル)
M.2 SSD : 1TB (NVMe)
保証期間 : 3年間センドバック修理保証・24時間×365日電話サポート
NEXTGEAR JG-A5G60(1周年記念モデル)

CPU : AMD Ryzen™ 5 4500 プロセッサー
グラフィックス : NVIDIA® GeForce RTX™ 4060
メモリ標準容量 : 16GB (8GB×2 / デュアルチャネル)
M.2 SSD : 1TB (NVMe)
保証期間 : 3年間センドバック修理保証・24時間×365日電話サポート
G TUNE FG-A7A7X

CPU : AMD Ryzen™ 7 9800X3D プロセッサ
グラフィックス : AMD Radeon™ RX 7700 XT
メモリ標準容量 : 32GB (16GB×2 / デュアルチャネル
M.2 SSD : 2TB (NVMe Gen4×4)
ドライブ仕様 :DVDスーパーマルチドライブ
無線 :Wi-Fi 6E( 最大2.4Gbps )対応 IEEE 802.11 ax/ac/a/b/g/n準拠 + Bluetooth 5内蔵
保証期間 : 3年間センドバック修理保証・24時間×365日電話サポート
関連記事

Unityで実装するローグライクなマップ自動生成
ローグライクゲームでよく使われそうなマップ生成方法に焦点を当ててみたいと思います。
ローグライクのマップはランダムに生成された部屋と通路で構成されていて、毎回異なるレイアウトのマップが自動的に作られます。
この記事ではその基本的な作り方をやってみます。

ドルアーガの塔みたいな薄い壁の迷路を作る
薄い壁の2Dダンジョンを作ってみたいと思います。
1マスに上下左右の壁を設置する感じです。

ウィザードリィのような疑似3Dダンジョンを作る
ウィザードリィのような疑似3DダンジョンをUnity2Dで作成してみたいと思います。

見下ろし2Dマップ上でプレイヤーを動かす
プレイヤーを2Dマップ上で移動させてみます。
見下ろし型のRPGとかでありそうなやつです。

テキストデータからマップを作ってみる
Unity2Dでテキストのデータを用いた簡単な2Dのマップ作成をしてみたいと思います。
色々なゲームで使えそうです。