/// <summary> /// 区画を分割する /// </summary> /// <param name="bVertical">垂直分割するかどうか</param> private static void SplitDivison(bool bVertical) { // 末尾の要素を取り出し DgDivision parent = _divList[_divList.Count - 1]; _divList.Remove(parent); // 子となる区画を生成 DgDivision child = new DgDivision(); if (bVertical) { // ▼縦方向に分割する if (CheckDivisionSize(parent.Outer.Height) == false) { // 縦の高さが足りない // 親区画を戻しておしまい _divList.Add(parent); return; } // 分割ポイントを求める int a = parent.Outer.Top + (MIN_ROOM + OUTER_MERGIN); int b = parent.Outer.Bottom - (MIN_ROOM + OUTER_MERGIN); // AB間の距離を求める int ab = b - a; // 最大の部屋サイズを超えないようにする ab = Mathf.Min(ab, MAX_ROOM); // 分割点を決める int p = a + Random.Range(0, ab + 1); // 子区画に情報を設定 child.Outer.Set( parent.Outer.Left, p, parent.Outer.Right, parent.Outer.Bottom); // 親の下側をp地点まで縮める parent.Outer.Bottom = child.Outer.Top; } else { // ▼横方向に分割する if (CheckDivisionSize(parent.Outer.Width) == false) { // 横幅が足りない // 親区画を戻しておしまい _divList.Add(parent); return; } // 分割ポイントを求める int a = parent.Outer.Left + (MIN_ROOM + OUTER_MERGIN); int b = parent.Outer.Right - (MIN_ROOM + OUTER_MERGIN); // AB間の距離を求める int ab = b - a; // 最大の部屋サイズを超えないようにする ab = Mathf.Min(ab, MAX_ROOM); // 分割点を求める int p = a + Random.Range(0, ab + 1); // 子区画に情報を設定 child.Outer.Set( p, parent.Outer.Top, parent.Outer.Right, parent.Outer.Bottom); // 親の右側をp地点まで縮める parent.Outer.Right = child.Outer.Left; } // 次に分割する区画をランダムで決める if (Random.Range(0, 2) == 0) { // 子を分割する _divList.Add(parent); _divList.Add(child); } else { // 親を分割する _divList.Add(child); _divList.Add(parent); } // 分割処理を再帰呼び出し (分割方向は縦横交互にする) SplitDivison(!bVertical); }
/// <summary> /// 指定した部屋の間を通路でつなぐ /// </summary> /// <param name="divA">部屋1</param> /// <param name="divB">部屋2</param> /// <param name="bGrandChild">孫チェックするかどうか</param> /// <returns>つなぐことができたらtrue</returns> private static bool CreateRoad(DgDivision divA, DgDivision divB, bool bGrandChild=false) { if (divA.Outer.Bottom == divB.Outer.Top || divA.Outer.Top == divB.Outer.Bottom) { // 上下でつながっている // 部屋から伸ばす通路の開始位置を決める int x1 = Random.Range(divA.Room.Left, divA.Room.Right); int x2 = Random.Range(divB.Room.Left, divB.Room.Right); int y = 0; if (bGrandChild) { // すでに通路が存在していたらその情報を使用する if(divA.HasRoad()) { x1 = divA.Road.Left; } if(divB.HasRoad()) { x2 = divB.Road.Left; } } if (divA.Outer.Top > divB.Outer.Top) { // B - A (Bが上側) y = divA.Outer.Top; // 通路を作成 divA.CreateRoad(x1, y + 1, x1 + 1, divA.Room.Top); divB.CreateRoad(x2, divB.Room.Bottom, x2 + 1, y); } else { // A - B (Aが上側) y = divB.Outer.Top; // 通路を作成 divA.CreateRoad(x1, divA.Room.Bottom, x1 + 1, y); divB.CreateRoad(x2, y, x2 + 1, divB.Room.Top); } FillDgRectRoad(divA.Road); FillDgRectRoad(divB.Road); // 通路同士を接続する FillHLine(x1, x2, y); // 通路を作れた return true; } if (divA.Outer.Left == divB.Outer.Right || divA.Outer.Right == divB.Outer.Left) { // 左右でつながっている // 部屋から伸ばす通路の開始位置を決める int y1 = Random.Range(divA.Room.Top, divA.Room.Bottom); int y2 = Random.Range(divB.Room.Top, divB.Room.Bottom); int x = 0; if(bGrandChild) { // すでに通路が存在していたらその情報を使う if(divA.HasRoad()) { y1 = divA.Road.Top; } if(divB.HasRoad()) { y2 = divB.Road.Top; } } if (divA.Outer.Left > divB.Outer.Left) { // B - A (Bが左側) x = divA.Outer.Left; // 通路を作成 divB.CreateRoad(divB.Room.Right, y2, x, y2 + 1); divA.CreateRoad(x + 1, y1, divA.Room.Left, y1 + 1); } else { // A - B (Aが左側) x = divB.Outer.Left; divA.CreateRoad(divA.Room.Right, y1, x, y1 + 1); divB.CreateRoad(x, y2, divB.Room.Left, y2 + 1); } FillDgRectRoad(divA.Road); FillDgRectRoad(divB.Road); // 通路同士を接続する FillVLine(y1, y2, x); // 通路を作れた return true; } // つなげなかった return false; }
/// <summary> /// DgRectの範囲を塗りつぶす /// </summary> /// <param name="rect">矩形情報</param> private static void FillDgRectRoad(DgDivision.DgRect r) { _layer.FillRectLTRB(r.Left, r.Top, r.Right, r.Bottom, 2); }
/// <summary> /// 最初の区画を作る /// </summary> /// <param name="left">左</param> /// <param name="top">上</param> /// <param name="right">右</param> /// <param name="bottom">下</param> private static void CreateDivision(int left, int top, int right, int bottom) { DgDivision div = new DgDivision(); div.Outer.Set(left, top, right, bottom); _divList.Add(div); }