void BuildTexture()
    {
        TileDataMap map = new TileDataMap(size_x, size_y);

        int       texWidth  = size_x * tileResolution;
        int       texHeight = size_y * tileResolution;
        Texture2D texture   = new Texture2D(texWidth, texHeight);

        Color[][] tiles = ChopUpTiles();

        for (int y = 0; y < size_y; y++)
        {
            for (int x = 0; x < size_x; x++)
            {
                Color[] p = tiles[map.GetTileAt(x, y)];
                texture.SetPixels(x * tileResolution, y * tileResolution, tileResolution, tileResolution, p);
            }
        }

        texture.filterMode = FilterMode.Point;
        texture.Apply();

        MeshRenderer mesh_renderer = GetComponent <MeshRenderer>();

        mesh_renderer.sharedMaterials[0].mainTexture = texture;

        Debug.Log("Finished textures");
    }
Beispiel #2
0
        /// <summary>
        /// 更に処理を追加実行する
        /// </summary>
        /// <param name="tildeDataMap"></param>
        /// <returns></returns>
        public async UniTask ExecuteFurher(TileDataMap prevTildeDataMap)
        {
            IsExecuting = true;

            await ExecuteFurtherInternal(prevTildeDataMap);

            IsExecuting = false;
        }
Beispiel #3
0
        public void Setup(TileDataMap tileDataMap)
        {
            _tileDataMap = tileDataMap;

            _width  = tileDataMap.Width;
            _height = tileDataMap.Height;

            _array = new int[_width, _height];
        }
Beispiel #4
0
        public IEnumerator <float> Build(TileDataMap tileDataMap, MapRectData mapRect)
        {
            for (int i = 0; i < mapRect.RectCount - 1; ++i)
            {
                CreateRoad(tileDataMap, mapRect, i, i + 1);

                yield return(0.5f);
            }
        }
Beispiel #5
0
        /// <summary>
        /// 処理を実行する
        /// </summary>
        public async UniTask Execute(TileDataMap prevTildeDataMap)
        {
            // 最初はすべて壁にする
            TileDataMap.AllTilesSetWall();

            IsExecuting = true;

            await ExecuteInternal(prevTildeDataMap);

            IsExecuting = false;
        }
Beispiel #6
0
        public static RoomData FindRoomData(this TileDataMap self, ICharaController chara)
        {
            var pos = chara.Model.CellPosition.Value;

            if (self.TryGetRoomData(pos.x, pos.y, out var roomData))
            {
                return(roomData);
            }

            return(null);
        }
Beispiel #7
0
        /// <summary>
        /// 自分の周りの座標で攻撃できる場所を探す
        /// </summary>
        protected bool TryGetAttackTargetPosition(TileFlag targetTileFlag, out Vector2Int targetPos)
        {
            targetPos = Vector2Int.zero;
            _targets.Clear();

            // 現在の座標の周りを調べ行ける場所を目的地とする
            var pos      = _unit.Model.CellPosition.Value;
            var dirArray = Utility.Map.GetDirArray(true);

            for (int i = 0, size = dirArray.GetLength(0); i < size; ++i)
            {
                var addX = dirArray[i, 0];
                var addY = dirArray[i, 1];

                var nextX = pos.x + addX;
                var nextY = pos.y + addY;

                if (!TileDataMap.InRange(nextX, nextY))
                {
                    continue;
                }

                var tileFlag = TileDataMap.GetTileFlag(nextX, nextY);

                // 指定したTileFlagか
                if (!tileFlag.HasAny(targetTileFlag))
                {
                    continue;
                }

                // 斜めの場合は障害物を貫通できるかどうか確認
                if (addX != 0 && addY != 0)
                {
                    // どちらかに障害物があるか
                    var tmp = TileFlag.None;
                    tmp |= _tileDataMap.GetTileFlag(pos.x + addX, pos.y);
                    tmp |= _tileDataMap.GetTileFlag(pos.x, pos.y + addY);

                    // その障害物を越えて攻撃できるか
                    if (!_unit.Model.CanDiagonalAttackTileFlag(tmp))
                    {
                        // 攻撃できないので失敗
                        continue;
                    }
                }

                targetPos = new Vector2Int(nextX, nextY);

                return(true);
            }

            return(false);
        }
Beispiel #8
0
        public IEnumerator <float> ExecuteDebug(TileDataMap prevTildeDataMap)
        {
            // 最初はすべて壁にする
            TileDataMap.AllTilesSetWall();

            IsExecuting = true;

            var enumerator = ExecuteInternal(prevTildeDataMap);

            while (enumerator.MoveNext())
            {
                yield return(enumerator.Current);
            }

            IsExecuting = false;
        }
Beispiel #9
0
        /// <summary>
        /// 部屋を作成する
        /// </summary>
        /// <returns></returns>
        private IEnumerator <float> CreateRoom()
        {
            for (int i = 0; i < MapRect.RectCount; ++i)
            {
                var rectData = MapRect[i];
                var rect     = rectData.rect;

                // 矩形の大きさを計算
                var w = rect.width - 3;
                var h = rect.height - 3;

                // 区画に入る最小部屋の余裕を求める
                var cw = w - _data.RoomMinSize;
                var ch = h - _data.RoomMinSize;

                // 部屋の大きさを決定する
                var sw = UnityEngine.Random.Range(0, cw + 1);
                var sh = UnityEngine.Random.Range(0, ch + 1);
                var rw = w - sw;
                var rh = h - sh;

                // 部屋の位置を決定する
                var rx = UnityEngine.Random.Range(0, sw + 1) + 2;
                var ry = UnityEngine.Random.Range(0, sh + 1) + 2;

                // 求めた結果から部屋の情報を設定
                rectData.room.xMin = rect.xMin + rx;
                rectData.room.yMin = rect.yMin + ry;
                rectData.room.xMax = rect.xMin + rx + rw;
                rectData.room.yMax = rect.yMin + ry + rh;

                var room = rectData.room;

                // 部屋を作る
                TileDataMap.FillRect(room.xMin, room.yMin, room.xMax, room.yMax, TileFlag.Floor);

                yield return(0.5f);
            }
        }
Beispiel #10
0
        /// <summary>
        /// 処理を実行する
        /// </summary>
        protected override IEnumerator <float> ExecuteInternal(TileDataMap prevTildeDataMap)
        {
            _splitter = _splitFactory.Create();

            MapRect = new MapRectData();

            // 全体を一つの区画にする
            // Width&Heightが20の場合
            // (0, 0, 20, 20)になる。
            // 区画が (0, 0, 10, 20), (10, 0, 20, 20)
            // となった場合、引き算するだけで
            // 10 - 0 = 10
            // 20 - 10 = 10
            // とマスの幅が求まり
            //   for (int x = 0; x < w; ++x)
            // とすると区画のループ処理がかける

            var extra = 3;

            MapRect.CreateRect(0 + extra, 0 + extra, Width - extra, Height - extra);

            // 区画を作る
            var splitEnumerator = _splitter?.SplitRect(_data, MapRect);

            while (splitEnumerator.MoveNext())
            {
                yield return(splitEnumerator.Current);
            }

            // 部屋を作る
            var roomEnumerator = CreateRoom();

            while (roomEnumerator.MoveNext())
            {
                yield return(roomEnumerator.Current);
            }

            // 道を作る
            _roadBuilder = _roadFactory.Create(SplitConst.RoadBuilderType.Simple);

            var roadEnumerator = _roadBuilder.Build(TileDataMap, MapRect);

            while (roadEnumerator.MoveNext())
            {
                yield return(roadEnumerator.Current);
            }

            // 前マップの下階段の位置に部屋を作成する
            // 下り階段の場所が部屋なら何もしない
            if (prevTildeDataMap != null)
            {
                var prevRoomEnumerator = CreateEntrance(prevTildeDataMap);
                while (prevRoomEnumerator.MoveNext())
                {
                    yield return(prevRoomEnumerator.Current);
                }
            }
            else
            {
                // マップだけ作成しておく
                TileDataMap.BuildRoomMap();
            }

            // 部屋に対して道が重なっていた場合、その道を取り除く
            RemoveExtraRoad();

            // 下階段を作る
            var pos = GetRandomRoomCellPos();

            TileDataMap.SetStepDownFlag(pos.x, pos.y);
        }
Beispiel #11
0
 protected override IEnumerator <float> ExecuteFurtherInternal(TileDataMap prevTildeDataMap)
 {
     yield break;
 }
Beispiel #12
0
        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);
                }
            }
        }
Beispiel #13
0
 public TileDataMapScanner(TileDataMap tileDataMap)
 {
     _tileDataMap = tileDataMap;
     _search      = Utility.Algorithm.Search.Instance;
 }
Beispiel #14
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));
        }
Beispiel #15
0
 public TileDataMapSearcher(TileDataMap tileDataMap)
 {
     _tileDataMap = tileDataMap;
 }
Beispiel #16
0
 public static TileData GetTile(this TileDataMap self, in Vector2Int pos) =>
Beispiel #17
0
        /// <summary>
        /// 部屋と部屋をつなぐ道を作成する
        /// </summary>
        /// <returns></returns>
        private void CreateRoad(TileDataMap tileDataMap, MapRectData mapRect, int indexA, int indexB)
        {
            var dataA = mapRect[indexA];
            var dataB = mapRect[indexB];

            var rectA = dataA.rect;
            var rectB = dataB.rect;
            var roomA = dataA.room;
            var roomB = dataB.room;

            var roadData = new RoadData();

            System.Predicate <TileData> createRoadData =
                (tileData_) =>
            {
                roadData.Add(tileData_.Pos);
                return(true);
            };

            // 区画は上下左右のどちらでつながっているかで処理を分ける
            if (rectA.yMax == rectB.yMin || rectA.yMin == rectB.yMax)
            {
                var x1 = Utility.Random.MaxIncludedRange(roomA.xMin, roomA.xMax - 1);
                var x2 = Utility.Random.MaxIncludedRange(roomB.xMin, roomB.xMax - 1);

                int y;

                // Aのほうが左
                var isLeftA = x1 < x2;

                var left  = Mathf.Min(x1, x2);
                var right = Mathf.Max(x1, x2) + 1;

                if (rectA.yMin > rectB.yMin)
                {
                    // B
                    // A
                    y = rectA.yMin;

                    if (isLeftA)
                    {
                        // Bと横道を繋ぐ道を作る
                        tileDataMap.FillRectRoad(x2, roomB.yMax, x2 + 1, y, createRoadData);

                        tileDataMap.FillRectRoadReverse(left, y, right, y + 1, createRoadData);

                        // Aと横道を繋ぐ道を作る
                        tileDataMap.FillRectRoad(x1, y + 1, x1 + 1, roomA.yMin, createRoadData);
                    }
                    else
                    {
                        // Bと横道を繋ぐ道を作る
                        tileDataMap.FillRectRoad(x2, roomB.yMax, x2 + 1, y, createRoadData);

                        tileDataMap.FillRectRoad(left, y, right, y + 1, createRoadData);

                        // Aと横道を繋ぐ道を作る
                        tileDataMap.FillRectRoad(x1, y + 1, x1 + 1, roomA.yMin, createRoadData);
                    }
                }
                else
                {
                    // A
                    // B
                    y = rectB.yMin;

                    if (isLeftA)
                    {
                        tileDataMap.FillRectRoad(x1, roomA.yMax, x1 + 1, y, createRoadData);
                        tileDataMap.FillRectRoad(left, y, right, y + 1, createRoadData);
                        tileDataMap.FillRectRoad(x2, y + 1, x2 + 1, roomB.yMin, createRoadData);
                    }
                    else
                    {
                        tileDataMap.FillRectRoad(x1, roomA.yMax, x1 + 1, y, createRoadData);
                        tileDataMap.FillRectRoadReverse(left, y, right, y + 1, createRoadData);
                        tileDataMap.FillRectRoad(x2, y + 1, x2 + 1, roomB.yMin, createRoadData);
                    }
                }

                // AとB両方に道のデータをもたせる
                dataA.roads.Add(roadData);

                return;
            }

            if (rectA.xMax == rectB.xMin || rectA.xMin == rectB.xMax)
            {
                var y1 = Utility.Random.MaxIncludedRange(roomA.yMin, roomA.yMax - 1);
                var y2 = Utility.Random.MaxIncludedRange(roomB.yMin, roomB.yMax - 1);

                int x;

                // Aのほうが上
                var isTopA = y1 < y2;

                var top    = Mathf.Min(y1, y2);
                var bottom = Mathf.Max(y1, y2) + 1;


                if (rectA.xMin > rectB.xMin)
                {
                    // BA
                    x = rectA.xMin;

                    if (isTopA)
                    {
                        tileDataMap.FillRectRoad(roomB.xMax, y2, x, y2 + 1, createRoadData);
                        tileDataMap.FillRectRoadReverse(x, top, x + 1, bottom, createRoadData);
                        tileDataMap.FillRectRoad(x + 1, y1, roomA.xMin, y1 + 1, createRoadData);
                    }
                    else
                    {
                        tileDataMap.FillRectRoad(roomB.xMax, y2, x, y2 + 1, createRoadData);
                        tileDataMap.FillRectRoad(x, top, x + 1, bottom, createRoadData);
                        tileDataMap.FillRectRoad(x + 1, y1, roomA.xMin, y1 + 1, createRoadData);
                    }
                }
                else
                {
                    // AB
                    x = rectB.xMin;

                    if (isTopA)
                    {
                        tileDataMap.FillRectRoad(roomA.xMax, y1, x, y1 + 1, createRoadData);
                        tileDataMap.FillRectRoad(x, top, x + 1, bottom, createRoadData);
                        tileDataMap.FillRectRoad(x + 1, y2, roomB.xMin, y2 + 1, createRoadData);
                    }
                    else
                    {
                        tileDataMap.FillRectRoad(roomA.xMax, y1, x, y1 + 1, createRoadData);
                        tileDataMap.FillRectRoadReverse(x, top, x + 1, bottom, createRoadData);
                        tileDataMap.FillRectRoad(x + 1, y2, roomB.xMin, y2 + 1, createRoadData);
                    }
                }

                // AとB両方に道のデータをもたせる
                dataA.roads.Add(roadData);

                return;
            }
        }
Beispiel #18
0
 protected abstract IEnumerator <float> ExecuteInternal(TileDataMap prevTildeDataMap);