void SetGround(JH_Island land) { //그리드에서 선의 시작점의 좌표를 잡는다. int x, y, count = 0; x = Random.Range(0, land.arrWidth - land.width); y = Random.Range(0, land.arrHeight - land.height); land.startPos = new Vector2Int(x, y); while (true) { //확률테이블 값에 따라 칸수 채우기 int repeat = GetPercentage(groundPer); repeat = (repeat > land.width - count) ? (land.width - count) : repeat; for (int i = 0; i < repeat; i++, count++) { //Debug.Log($"x : {(x + count).ToString()}, y : {y.ToString()}, maxWidth : {land.maxWidth}, maxHeight : {land.maxHeight}"); land.arr[y, x + count] = (int)Tile.GRASS; SetUnderGround(land, x + count, y); } //지상의 경사를 만듦 int slp = (int)(GetPercentage(groundSlpPer) * (land.width / 30f)); // 다 그리면 나감 if (count == land.width) { land.endPos = new Vector2Int(x + count - 1, y); break; } if (Random.Range(0, 2) == 0) { if (y - slp < 0) { y += slp; } else { y -= slp; } } else { if (y + slp > land.arrHeight - 1) { y -= slp; } else { y += slp; } } } }
void InitLand(JH_Island land) { for (int y = 0; y < land.arrHeight; y++) { for (int x = 0; x < land.arrWidth; x++) { land.arr[y, x] = (int)Tile.AIR; } } }
void SetUnderGround(JH_Island land, int x, int y) { int repeat = GetPercentage(underGroundPer); repeat = (Random.Range(0, 2) == 0) ? repeat + land.height : -repeat + land.height; repeat = Mathf.Clamp(repeat, 1, land.arrHeight - y); for (int i = 1; i < repeat; i++) { land.arr[y + i, x] = (int)Tile.DIRT; } }
public JH_Island GenerateIsland(int posX, int posY, int wid = 0, int hei = 0, int maxWidth = 0, int maxHeight = 0) { //Debug.Log($"posX : {posX} , posY : {posY}"); if (wid == 0) { wid = Random.Range(30, 50); } if (hei == 0) { hei = wid / 2; } maxWidth = (maxWidth == 0) ? IslandRandomGenerator.WIDTH : maxWidth; maxHeight = (maxHeight == 0) ? IslandRandomGenerator.HEIGHT : maxHeight; JH_Island land = _irg.GenerateIsland(wid, hei, maxWidth, maxHeight); land.pos = new Vector2Int(posX, posY); land.midPos = land.pos + new Vector2Int(land.arrWidth / 2, -land.arrHeight / 2); return(land); }
// 섬 한개 생성하는 함수. 매개변수로 너비 높이 받아오고, 없으면 그냥 고정 청크 사이즈로 받아옴. public JH_Island GenerateIsland(int wid = 0, int hei = 0, int maxWidth = 0, int maxHeight = 0) { //넓이와 높이 설정 wid = (wid == 0) ? Random.Range(minWidth, maxWidth) : wid; hei = (hei == 0) ? Random.Range(minHeight, maxHeight) : hei; maxWidth = (maxWidth == 0) ? WIDTH : maxWidth; maxHeight = (maxHeight == 0) ? HEIGHT : maxHeight; JH_Island land = new JH_Island(wid, hei, maxWidth, maxHeight); InitLand(land); SetGround(land); CarveUnderground(land); for (int i = 0; i < 3; i++) { PutWoodenPlatform(land); } return(land); }
void PutIslandInArr(JH_Island land) { if (land == null) { return; } int posX, posY; int x = land.pos.x; int y = land.pos.y + intervalY - 1; int maxX = land.arrWidth; int maxY = land.arrHeight; //Debug.Log($"maxX : {maxX} maxY : {maxY} y : {y} arrheight : {arrHei}"); maxX = Mathf.Clamp(maxX, 0, arrWid - x); y = Mathf.Clamp(y, 0, arrHei - 1); //Debug.Log($"maxX : {maxX} maxY : {maxY}"); for (int i = 0; i < maxX; i++) { for (int j = 0; j < maxY; j++) { posX = x + i; posY = y - j; //Debug.Log($"posX = {posX} posY = {posY} x = {x} y = {y} j = {j} i = {i}"); if (land.arr[j, i] >= 0) { allTiles[posY, posX] = land.arr[j, i]; } } } }
void CarveUnderground(JH_Island land) { int x, y, j, repeat; for (repeat = 0; repeat < land.width / 5; repeat++) { //왼쪽 부터 x = (int)land.startPos.x + repeat; //y값 구하기 for (y = 0; y < land.arrHeight; y++) { if (land.arr[y, x] == (int)Tile.GRASS) { break; } } for (j = (int)(2 * (repeat + land.height / 5f)); (y + j) < land.arrHeight; j++) { land.arr[y + j, x] = (int)Tile.AIR; } //오른쪽 부터 x = (int)land.endPos.x - repeat; //y값 구하기 for (y = 0; y < land.arrHeight; y++) { if (land.arr[y, x] == (int)Tile.GRASS) { break; } } for (j = (int)(2 * (repeat + land.height / 5f)); (y + j) < land.arrHeight; j++) { land.arr[y + j, x] = (int)Tile.AIR; } } }
//다리 생성 메소드 void PutBridge(JH_Island land1, JH_Island land2) { // 다리의 시작지점과 끝지점 설정. // 배열에서의 Y좌표 반전때문에 startPos와 endPos에 -를 곱해서 넣어야 함. Vector2 startPos = new Vector2(land1.pos.x + land1.endPos.x, land1.pos.y - land1.endPos.y); Vector2 endPos = new Vector2(land2.pos.x + land2.startPos.x - 8, land2.pos.y - land2.startPos.y); //Debug.Log($"startPos : {startPos}, endPos : {endPos}"); //Debug.Log($"startpos : {startPos.ToString()}, endpos : {endPos.ToString()}"); int repeat = 0, i, wid, hei; Vector2 interval = (endPos - startPos); Vector2 newPos = startPos; int interX = (int)Mathf.Abs(interval.x); int interY = (int)Mathf.Abs(interval.y); //다리로 놓을 섬 갯수 설정 int re1, re2; for (i = 1; true; i++) { if (interX / i <= 20) { re1 = i; break; } } for (i = 1; true; i++) { if (interY / i <= 4) { re2 = i; break; } } repeat = Mathf.Max(re1, re2); repeat++; //갯수에 따른 간격 설정 interval /= repeat; interX = Mathf.Max(13, (int)Mathf.Abs(interval.x)); newPos += interval / 2; //실질적으로 다리 생성하는 반복문 for (i = 0; i < repeat; i++) { wid = Random.Range(interX - 6, interX - 3); /* * if(i == repeat-1) * { * wid = (int)(endPos.x - newPos.x - 3); * }*/ hei = wid / 3; JH_Island land = _irg.GenerateBridge((int)newPos.x, (int)newPos.y, wid, hei); islands.Add(land); //SpawnTile((int)newPos.x, (int)newPos.y + 70, (int)IslandRandomGenerator.Tile.GRASS); newPos += interval; } }
//사이즈는 적당히 public JH_Island GenerateBridge(int posX, int posY, int wid, int hei) { if (wid <= 0 || hei <= 0) { return(null); } JH_Island land = new JH_Island(wid, hei, wid, hei + 2); InitLand(land); land.pos = new Vector2Int(posX, posY); land.midPos = land.pos + new Vector2Int(land.arrWidth / 2, -land.arrHeight / 2); Vector2Int startPos = Vector2Int.up; land.startPos = startPos; land.endPos = startPos + Vector2Int.right * wid; int diffStart = Random.Range(0, wid / 3 * 2); if (diffStart <= 1) { diffStart = 0; } int diffEnd = Random.Range(diffStart, wid); if (diffEnd >= wid - 1) { diffEnd = wid; } int upDown = Random.Range(0, 2) == 0 ? 1 : -1; int x, y; // 표면 깔기 for (x = 0; x < diffStart; x++) { land.arr[startPos.y, x] = (int)Tile.GRASS; } startPos.y += upDown; for (x = diffStart; x < diffEnd; x++) { land.arr[startPos.y, x] = (int)Tile.GRASS; } startPos.y -= upDown; for (x = diffEnd; x < wid; x++) { land.arr[startPos.y, x] = (int)Tile.GRASS; } // 표면 깔기 if (upDown == -1) { upDown = 0; } //지하 채우기 int left = 0, right = 0; for (y = 0; y < hei; y++) { left += Random.Range(y, 2); right += Random.Range(y, 2); for (x = left; x < wid - right; x++) { if (land.arr[y + 1 + upDown, x] < 0) { land.arr[y + 1 + upDown, x] = (int)Tile.DIRT; } } } return(land); }
void PutWoodenPlatform(JH_Island land, int x = -1, int width = 0, int height = 0) { if (land.width < 10) { return; } if (width == 0) { width = Random.Range(3, 6); } if (height == 0) { height = Random.Range(3, 6); } if (x == -1) { x = Random.Range(land.startPos.x + 1, land.endPos.x - width - 1); } Vector2Int left = Vector2Int.right * x; Vector2Int right = Vector2Int.right * (x + width); //플랫폼 다리 위치 잡아줌 int i; for (i = 0; i < land.arrHeight; i++) { //Debug.Log($"x : {x}, left.x : {left.x}, i : {i}"); if (land.arr[i, left.x] != (int)Tile.AIR) { left.y = i - 1; break; } } for (i = 0; i < land.arrHeight; i++) { if (land.arr[i, right.x] != (int)Tile.AIR) { right.y = i - 1; break; } } //==================== // 플랫폼 다리 놓아줌 //Debug.Log($"height : {height}, width : {width}"); int highPos = (left.y < right.y) ? left.y : right.y; //섬이 청크 기준 너무 높은곳에 있어 플랫폼을 놓지 못하는 상황일 때 if (highPos < height) { return; } highPos = Mathf.Clamp(highPos - height + 1, 0, land.arrHeight - 1); for (i = left.y; i > highPos; i--) { land.arr[i, left.x] = (int)Tile.WOODPLATFORM_ROD; } //플랫폼 다리와 판 교차점 land.arr[i, left.x] = (int)Tile.WOODPLATFORM_TOPROD; for (i = right.y; i > highPos; i--) { land.arr[i, right.x] = (int)Tile.WOODPLATFORM_ROD; } //플랫폼 다리와 판 교차점 land.arr[i, right.x] = (int)Tile.WOODPLATFORM_TOPROD; //판 깔아줌 for (i = left.x - 1; i <= right.x + 1; i++) { if (land.arr[highPos, i] != (int)Tile.WOODPLATFORM_TOPROD) { land.arr[highPos, i] = (int)Tile.WOODPLATFORM_TOP; } } }