// 방 사이에 최단거리 타일들 구하기 void GetShortestPathPointTilesBetweenRooms(Room _baseRoom, Room _targetRoom, out RandomMapGenerateData _baseTile, out RandomMapGenerateData _shortTile) { List <RandomMapGenerateData> baseEdgeList = _baseRoom.m_edgeTileList; List <RandomMapGenerateData> checkEdgeList = _targetRoom.m_edgeTileList; _baseTile = null; _shortTile = null; float shortestTileDis = float.MaxValue; for (int bel = 0; bel < baseEdgeList.Count; bel++) { RandomMapGenerateData beld = baseEdgeList[bel]; for (int cel = 0; cel < checkEdgeList.Count; cel++) { RandomMapGenerateData celd = checkEdgeList[cel]; float disX = beld.m_xIndex - celd.m_xIndex; float disY = beld.m_yIndex - celd.m_yIndex; float tileDis = disX * disX + disY * disY; if (tileDis <= shortestTileDis) { shortestTileDis = tileDis; _baseTile = beld; _shortTile = celd; } } } }
// 방 사이 최단거리 구하기 float GetShortestDistanceBetweenRooms(Room _baseRoom, Room _targetRoom) { List <RandomMapGenerateData> baseEdgeList = _baseRoom.m_edgeTileList; List <RandomMapGenerateData> checkEdgeList = _targetRoom.m_edgeTileList; float shortestTileDis = float.MaxValue; for (int bel = 0; bel < baseEdgeList.Count; bel++) { RandomMapGenerateData beld = baseEdgeList[bel]; for (int cel = 0; cel < checkEdgeList.Count; cel++) { RandomMapGenerateData celd = checkEdgeList[cel]; float disX = beld.m_xIndex - celd.m_xIndex; float disY = beld.m_yIndex - celd.m_yIndex; float tileDis = disX * disX + disY * disY; if (tileDis <= shortestTileDis) { shortestTileDis = tileDis; } } } return(shortestTileDis); }
void MakePassage() { for (int i = 0; i < m_passageList.Count; i++) { Passage p = m_passageList[i]; for (int k = 0; k < p.m_passageTileList.Count; k++) { RandomMapGenerateData data = p.m_passageTileList[k]; data.m_isWall = false; } } }
public void AddEdgeTile(RandomMapGenerateData _data) { // 이미 들어가 있으면 제외해서 집어넣기 for (int i = 0; i < m_edgeTileList.Count; i++) { RandomMapGenerateData inData = m_edgeTileList[i]; if (_data.m_xIndex == inData.m_xIndex && _data.m_yIndex == inData.m_yIndex) { return; } } m_edgeTileList.Add(_data); }
public void Clear() { for (int i = 0; i < m_tileList.Count; i++) { RandomMapGenerateData data = m_tileList[i]; data.m_isWall = true; } for (int i = 0; i < m_edgeTileList.Count; i++) { RandomMapGenerateData data = m_edgeTileList[i]; data.m_isWall = true; } m_tileList.Clear(); m_edgeTileList.Clear(); }
void FindEdgeTileInRooms() { for (int i = 0; i < m_roomList.Count; i++) { Room room = m_roomList[i]; for (int k = 0; k < room.m_tileList.Count; k++) { RandomMapGenerateData data = room.m_tileList[k]; for (int q = 0; q < m_tileDirOffSet.Length; q++) { TileDir dir = (TileDir)q; if (dir == TileDir.NE || dir == TileDir.NW || dir == TileDir.SE || dir == TileDir.SW) { continue; } int x = data.m_xIndex + m_tileDirOffSet[q].m_x; int y = data.m_yIndex + m_tileDirOffSet[q].m_y; if (!IsValidIndex(x, y)) { continue; } RandomMapGenerateData expandData = m_genData[x][y]; if (!expandData.m_isWall) { continue; } room.AddEdgeTile(expandData); } } } }
void GetPassageTiles() { for (int i = 0; i < m_passageList.Count; i++) { Passage p = m_passageList[i]; int sX = p.m_startX; int sY = p.m_startY; int eX = p.m_endX; int eY = p.m_endY; if (sX > eX) { sX = p.m_endX; sY = p.m_endY; eX = p.m_startX; eY = p.m_startY; } if (eX == sX && eY == sY) { // 통로가 1개의 타일로 연결된 경우. RandomMapGenerateData data = m_genData[sX][sY]; p.m_passageTileList.Add(data); continue; } if (eX == sX && eY != sY) { // 통로가 수직 int startY = eY < sY ? eY : sY; int endY = eY < sY ? sY : eY; for (int y = startY; y <= endY; y++) { RandomMapGenerateData data = m_genData[eX][y]; p.m_passageTileList.Add(data); } continue; } int pivotY = sY; float coe = (float)(eY - sY) / (float)(eX - sX); for (int x = sX; x <= eX; x++) { float fv = coe * (float)(x - sX) + (float)(sY); int quotient = (int)fv; int xIndex = x; int yIndex = pivotY; RandomMapGenerateData data = m_genData[xIndex][yIndex]; p.m_passageTileList.Add(data); if (pivotY != quotient) { int difQuotient = quotient - pivotY; if (difQuotient < 0) { for (int offset = difQuotient; offset < 0; offset++) { data = m_genData[xIndex][yIndex + offset]; p.m_passageTileList.Add(data); } } else { for (int offset = difQuotient; offset > 0; offset--) { data = m_genData[xIndex][yIndex + offset]; p.m_passageTileList.Add(data); } } pivotY += difQuotient; } } } }
public void AddGenData(RandomMapGenerateData _data) { m_roomSize++; m_tileList.Add(_data); }
void FindClosestRooms() { if (m_roomList.Count == 1) { return; } for (int i = 0; i < m_roomList.Count; i++) { Room baseRoom = m_roomList[i]; if (baseRoom.m_isConnectedToMainRoom && !baseRoom.m_isMainRoom) { continue; } Room ShortestRoom = GetShortestRoom(baseRoom); if (ShortestRoom == null) { Debug.Log(" 발생 불가능 "); } // 전체 알고리즘 // // 가장 최단 거리의 방을 찾았는데, 혹시 그 방이 baseRoom에 연결된 친구가 더 가깝다면, // 그 친구와 가장 짧은 거리의 방을 연결시켜주자. // 그런데 이미 새로운 친구가 그 짧은 거리의 방과 연결되어 있다면 // 더 이상 하지 않는다. Room shortestLinkedRoom = GetShortestLinkedRoom(baseRoom, ShortestRoom); if (shortestLinkedRoom != null) { // 아니라는 것은 더 짧은 길이의 방이 존재한다. // 그렇다면 이 방이 이미 연결이 되었는지 확인한다. // 만약에 연결이 되어있으면 해당 방은 더이상하지 않는다. if (shortestLinkedRoom.CheckAlreadyLinkedRoom(ShortestRoom)) { continue; } // 만약에 여기라면 합쳐햐나는 baseRoom을 더 가까이 있는 ShortestRoom으로 교체한다. baseRoom = shortestLinkedRoom; } RandomMapGenerateData baseTile = null; RandomMapGenerateData shortTile = null; GetShortestPathPointTilesBetweenRooms(baseRoom, ShortestRoom, out baseTile, out shortTile); m_passageList.Add(new Passage(baseTile.m_xIndex, baseTile.m_yIndex, shortTile.m_xIndex, shortTile.m_yIndex)); // 통로를 집어넣는다. baseRoom.LinkRoom(ShortestRoom); } }
void DetectingRoomsInTileDatas() { RandomMapGenerateData startData = GetStartData(); // 시작하는 놈 찾아옴. 그놈을 확장시킨다. Queue <RandomMapGenerateData> queue = new Queue <RandomMapGenerateData>(); while (true) { Room room = new Room(m_roomList.Count); room.AddGenData(startData); queue.Enqueue(startData); while (queue.Count != 0) { RandomMapGenerateData data = queue.Dequeue(); // 가져와서 검사한 다음 큐에 집어넣기 for (int i = 0; i < m_tileDirOffSet.Length; i++) { Coord2DSt coord = m_tileDirOffSet[i]; TileDir dir = (TileDir)i; if (dir == TileDir.NE || dir == TileDir.NW || dir == TileDir.SE || dir == TileDir.SW) { continue; } int x = data.m_xIndex + coord.m_x; int y = data.m_yIndex + coord.m_y; if (!IsValidIndex(x, y)) { continue; } RandomMapGenerateData genData = m_genData[x][y]; if (genData.m_isDetected == true) { continue; } genData.m_isDetected = true; if (!genData.m_isWall) { room.AddGenData(genData); queue.Enqueue(genData); } } } startData = GetStartData(); m_roomList.Add(room); queue.Clear(); if (startData == null) { break; } } }
void InitVariables() { m_mapWidth = 128; m_mapHeight = 72; // 맵 사이즈 m_fillRate = 60; // 맵을 얼마나 채울 것인가? m_numOfSmooth = 5; // 맵을 몇 번이나 부드럽게 할 것인가? m_deletRoomSize = 50; // 너무 작은 방은 삭제하는데 그 사이즈는? m_roomList = new List <Room>(); // 룸 리스트 초기화 m_genData = new RandomMapGenerateData[m_mapWidth][]; for (int i = 0; i < m_mapWidth; i++) { m_genData[i] = new RandomMapGenerateData[m_mapHeight]; } for (int y = 0; y < m_mapHeight; y++) { for (int x = 0; x < m_mapWidth; x++) { m_genData[x][y] = new RandomMapGenerateData(x, y); } } // 맵 생성시 사용하는 RandomMapGenrateData 초기화 m_tileDataAry = new TileData[m_mapWidth][]; for (int i = 0; i < m_mapWidth; i++) { m_tileDataAry[i] = new TileData[m_mapHeight]; } // 실제로 사용될 예정인 타일데이터 초기화 int numOfDir = System.Enum.GetNames(typeof(TileDir)).Length; m_tileDirOffSet = new Coord2DSt[numOfDir]; for (int i = 0; i < numOfDir; i++) { switch (((TileDir)i)) { case TileDir.E: m_tileDirOffSet[i] = new Coord2DSt(1, 0); break; case TileDir.SE: m_tileDirOffSet[i] = new Coord2DSt(1, -1); break; case TileDir.S: m_tileDirOffSet[i] = new Coord2DSt(0, -1); break; case TileDir.SW: m_tileDirOffSet[i] = new Coord2DSt(-1, -1); break; case TileDir.W: m_tileDirOffSet[i] = new Coord2DSt(-1, 0); break; case TileDir.NW: m_tileDirOffSet[i] = new Coord2DSt(-1, 1); break; case TileDir.N: m_tileDirOffSet[i] = new Coord2DSt(0, 1); break; case TileDir.NE: m_tileDirOffSet[i] = new Coord2DSt(1, 1); break; } } // 방향에 대해서 사용할 것 만들어 놨음.. m_passageList = new List <Passage>(); }