예제 #1
0
파일: Builder.cs 프로젝트: Toshizabeth/Ling
        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);
                }
            }
        }
예제 #2
0
        /// <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));
        }