//현재 지점에서 체크하는 지점의 G값을 계산 private int calcG(nodeDirection dir, int curG) { int diagonal = 14; int straight = 10; switch (dir) { case nodeDirection.UP_LEFT: case nodeDirection.UP_RIGHT: case nodeDirection.BOTTOM_LEFT: case nodeDirection.BOTTOM_RIGHT: return(curG + diagonal); case nodeDirection.LEFT: case nodeDirection.RIGHT: case nodeDirection.UP: case nodeDirection.BOTTOM: return(curG + straight); } //에러시 -1 return(-1); }
//피해야 하는 길인지 판정 private bool isCorner(int curX, int curY, nodeDirection dir) { switch (dir) { case nodeDirection.UP_LEFT: { //왼쪽 상단으로 넘어갈때 //바로 왼쪽이 벽 if (map[curX - 1, curY].property == nodeProp.WALL) { return(true); } //바로 위쪽이 벽 if (map[curX, curY - 1].property == nodeProp.WALL) { return(true); } } break; case nodeDirection.UP_RIGHT: { //오른쪽 상단으로 넘어갈때 //바로 오른쪽이 벽 if (map[curX + 1, curY].property == nodeProp.WALL) { return(true); } //바로 위쪽이 벽 if (map[curX, curY - 1].property == nodeProp.WALL) { return(true); } } break; case nodeDirection.BOTTOM_LEFT: { //좌측하단으로 넘어갈때 //바로 왼쪽이 벽 if (map[curX - 1, curY].property == nodeProp.WALL) { return(true); } //바로 아래쪽이 벽 if (map[curX, curY + 1].property == nodeProp.WALL) { return(true); } } break; case nodeDirection.BOTTOM_RIGHT: { //우측하단으로 넘어갈때 //바로 오른쪽이 벽 if (map[curX + 1, curY].property == nodeProp.WALL) { return(true); } //바로 아래쪽이 벽 if (map[curX, curY + 1].property == nodeProp.WALL) { return(true); } } break; } return(false); }
//선택된 블럭 주변을 탐색하는 함수 private bool searchAround(ref INode curTile) { for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { //방향 판정 nodeDirection dir = getDirection(j, i); //중앙부는 항상 자신이므로 패스 if (dir == nodeDirection.CENTER) { continue; } int txPos = curTile.xPos + j; int tyPos = curTile.yPos + i; //지정된 범위를 벗어나면 리턴 if (txPos < 0 || txPos > map.GetLength(0) - 1) { continue; } if (tyPos < 0 || tyPos > map.GetLength(1) - 1) { continue; } //벽이나 곡면 예외 처리 클로즈 리스트 예외 처리 //판정할 타일 캐싱 INode tile = map[txPos, tyPos]; //클로즈 리스트에 들어가있는 블럭이면 패스 if (CloseList.Contains(tile)) { continue; } //벽이면 패스 if (tile.property == nodeProp.WALL) { continue; } //피해야 하는 블럭 판정 if (isCorner(curTile.xPos, curTile.yPos, dir)) { continue; } //골이면 완료 if (isGoal(tile.xPos, tile.yPos)) { tile.parent = curTile; return(true); } //0이면 아직 거리계산이 안됐다는 의미 if (tile.F == 0) { tile.H = calcH(tile.xPos, tile.yPos); tile.G = calcG(dir, curTile.G); tile.parent = curTile; //거리계산이 안된 블럭은 무조건 들어간다. tile.stat = nodeStat.OPEN; OpenList.Add(tile); } else { //타일이 작성이 됐다면 값을 비교해서 작은쪽으로 수정 int tG = calcG(dir, curTile.G); if (tile.G > tG) { tile.G = tG; tile.parent = curTile; } } } } return(false); }