private IEnumerator <float> CreateEntrance(TileDataMap prevTildeDataMap) { if (prevTildeDataMap == null) { // 部屋のマップを作成する TileDataMap.BuildRoomMap(); yield break; } // 前マップの下階段の位置に部屋を作成する // 下り階段の場所が部屋なら何もしない var stepDownPos = prevTildeDataMap.StepDownPos; var tileData = TileDataMap.GetTile(stepDownPos.x, stepDownPos.y); if (tileData.HasFlag(TileFlag.Floor)) { // 部屋のマップを作成する TileDataMap.BuildRoomMap(); yield break; } // 3マスで部屋を作成 var w = Utility.Random.MaxIncludedRange(1, 1); var h = Utility.Random.MaxIncludedRange(1, 1); // どこかの部屋か道と連結したら終わり var xMin = stepDownPos.x - 1; // - w / 2; var xMax = stepDownPos.x + 1; // + w / 2; var yMin = stepDownPos.y - 1; // - h / 2; var yMax = stepDownPos.y + 1; // + h / 2; bool shouldCreateRoad = true; // 隣接しているかチェック for (int y = yMin; y < yMax; ++y) { for (int x = xMin; x < xMax; ++x) { if (!TileDataMap.InRange(x, y)) { continue; } if (TileDataMap.IsAdjacent(x, y, TileFlag.Floor | TileFlag.Road)) { shouldCreateRoad = false; break; } } } TileDataMap.FillRect(xMin, yMin, xMax, yMax, TileFlag.Floor, tileData_ => { return(true); }); // 部屋のマップを作成する TileDataMap.BuildRoomMap(); // 道を作る必要がある場合作成 if (shouldCreateRoad) { // 部屋マップの値を取得 var roomValue = TileDataMap.GetRoomIndex(stepDownPos.x, stepDownPos.y); // 一番近い部屋か道とつなげる var route = new Route.Tracking(); route.Setup(TileDataMap); // 自分の部屋は1とする。 // 自分以外の部屋か道が見つかったら終わり route.Execute(stepDownPos.x, stepDownPos.y, (tracking_, cellPos_, newValue_, oldValue_) => { // 自分の部屋か if (TileDataMap.EqualRoomMapValue(cellPos_.x, cellPos_.y, roomValue)) { // すでに書き込まれていたらスキップ if (oldValue_ == 1) { return(-1); } // 自分の部屋は 1 として書き込む return(1); } // 自分が2(部屋の外周)じゃないのに部屋の隣りにいるならばだめ if (newValue_ > 2) { if (Utility.Map.CallDirection(cellPos_.x, cellPos_.y, (x_, y_) => { // 自分の部屋があればおわり return(TileDataMap.EqualRoomMapValue(x_, y_, roomValue)); })) { return(-1); } } // 前後左右が自分以外の部屋か道ならおわり Utility.Map.CallDirection(cellPos_.x, cellPos_.y, (x_, y_) => { if (!TileDataMap.InRange(x_, y_)) { return(false); } if (TileDataMap.EqualRoomMapValue(x_, y_, roomValue)) { return(false); } // 部屋か道を見つける var tileFlag = TileDataMap.GetTileFlag(x_, y_); if (tileFlag.HasFlag(TileFlag.Floor) || tileFlag.HasFlag(TileFlag.Road)) { tracking_.ProcessFinish(); return(true); } return(false); }); return(0); }); // ルートを道にする var posList = route.GetRoute(route.ForceFinishPos, useDiagonal: false); foreach (var pos in posList) { // 部屋なら何もしない if (TileDataMap.GetTileFlag(pos.x, pos.y).HasFlag(TileFlag.Floor)) { continue; } TileDataMap.SetTileFlag(pos, TileFlag.Road); } } }
/// <summary> /// [x, y] から指定したタイル情報を返す /// </summary> public static TileData GetTile(this TileDataMap self, int x, int y) { Utility.Log.Assert(x >= 0 && x <= self.Width && y >= 0 && y <= self.Height, "範囲から飛び出してます"); return(self.GetTile(y * self.Width + x)); }