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"); }
/// <summary> /// 更に処理を追加実行する /// </summary> /// <param name="tildeDataMap"></param> /// <returns></returns> public async UniTask ExecuteFurher(TileDataMap prevTildeDataMap) { IsExecuting = true; await ExecuteFurtherInternal(prevTildeDataMap); IsExecuting = false; }
public void Setup(TileDataMap tileDataMap) { _tileDataMap = tileDataMap; _width = tileDataMap.Width; _height = tileDataMap.Height; _array = new int[_width, _height]; }
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); } }
/// <summary> /// 処理を実行する /// </summary> public async UniTask Execute(TileDataMap prevTildeDataMap) { // 最初はすべて壁にする TileDataMap.AllTilesSetWall(); IsExecuting = true; await ExecuteInternal(prevTildeDataMap); IsExecuting = false; }
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); }
/// <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); }
public IEnumerator <float> ExecuteDebug(TileDataMap prevTildeDataMap) { // 最初はすべて壁にする TileDataMap.AllTilesSetWall(); IsExecuting = true; var enumerator = ExecuteInternal(prevTildeDataMap); while (enumerator.MoveNext()) { yield return(enumerator.Current); } IsExecuting = false; }
/// <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); } }
/// <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); }
protected override IEnumerator <float> ExecuteFurtherInternal(TileDataMap prevTildeDataMap) { yield break; }
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); } } }
public TileDataMapScanner(TileDataMap tileDataMap) { _tileDataMap = tileDataMap; _search = Utility.Algorithm.Search.Instance; }
/// <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)); }
public TileDataMapSearcher(TileDataMap tileDataMap) { _tileDataMap = tileDataMap; }
public static TileData GetTile(this TileDataMap self, in Vector2Int pos) =>
/// <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; } }
protected abstract IEnumerator <float> ExecuteInternal(TileDataMap prevTildeDataMap);