타일 기반 게임을 프로그래밍하고 있으며 기본 타일 (잔디, 흙 등)이 있지만 타일이 잔디 / 흙이어야합니다.
왜 이런 일이 발생하는지 이해하지만 원하는 것은 잔디 나 흙의 임의의 연속적인 영역을 만드는 것입니다. 다음과 같이 더 의미가있는 것 :
타일 기반 게임을 프로그래밍하고 있으며 기본 타일 (잔디, 흙 등)이 있지만 타일이 잔디 / 흙이어야합니다.
왜 이런 일이 발생하는지 이해하지만 원하는 것은 잔디 나 흙의 임의의 연속적인 영역을 만드는 것입니다. 다음과 같이 더 의미가있는 것 :
답변:
당신이 할 수있는 일은 무작위로 다음과 같이 Voronoi 맵을 생성하는 것입니다.
center points
(검은 점 참조) 잔디 또는 흙인지 무작위로 결정하십시오.center point
먼지 나 잔디에 가장 가까운 지 확인하십시오 .이전에 수행 한 작업이 각 타일 (소음)에 대해 "코인 플립"인 경우 Voronoi 다이어그램을 생성하면 훨씬 더 나은 결과를 얻을 수 있습니다.
center points
를 다음 islands
과 같은 알고리즘 으로 나누면이를 개선 할 수 있습니다 .
centers points
하여로 지정합니다 leaders
.center points
. 그런 다음 잔디인지 흙인지를 결정하십시오. 이제 배열을 반복하고 각 타일이 더러움 지점이나 잔디 지점에 가장 가까운 지 결정하십시오. 어쩌면 어느 부분이 도전적인지 말해 주실 수 있습니까?
하이트 맵 생성에 일반적으로 사용되는 펄린 노이즈를 사용할 수 있습니다. 게임에서 펄린 노이즈
그런 다음지도의 한 영역에서 잔디 / 흙이 발생할 가능성이 얼마나 높은지 조언자로 높이를 사용할 수 있습니다.
예 (0-256의 펄린 노이즈 값) : 값이 200을 초과하면 잔디가 놓일 확률이 80 % (흙 20 %)입니다. 값이 100과 200 사이이면 잔디가 놓일 확률은 50 %입니다 (흙도 50 %). 값이 100 미만인 경우 잔디를 놓을 확률은 20 % (흙 80 %)입니다.
여기에 셀룰러 오토마타 방법의 내 버전은 그리드를 무작위로 채워서 시작 하고이 컬 컬러 오토마타 규칙을 몇 번 실행합니다.
그리고 동굴처럼 보이게됩니다
이 코드로 인덱스를 x & y 위치로 변환하고 다시 변환 할 수 있습니다.
public int TileIndex(int x, int y)
{
return y * Generator.Instance.Width + x;
}
public Vector2 TilePosition(int index)
{
float y = index / Generator.Instance.Width;
float x = index - Generator.Instance.Width * y;
return new Vector2(x, y);
}
동굴, 나무, 꽃, 잔디, 안개, 물 등 여러 가지 일 에이 목록을 사용하기 때문에 부울 목록을 반환합니다. 여러 가지 방법으로 여러 목록을 결합 할 수도 있습니다. 여기서 먼저 작은 동굴을 모두 제거한 다음 두 개의 임의 목록을 결합하십시오.
private int GetAdjacentCount(List<bool> list, Vector2 p)
{
int count = 0;
for (int y = -1; y <= 1; y++)
{
for (int x = -1; x <= 1; x++)
{
if (!((x == 0) && (y == 0)))
{
Vector2 point = new Vector2(p.x + x, p.y + y);
if (PathFinder.Instance.InsideMap(point))
{
int index = PathFinder.Instance.TileIndex(point);
if (list[index])
{
count++;
}
}
else
{
count++;
}
}
}
}
return count;
}
private List<bool> GetCellularList(int steps, float chance, int birth, int death)
{
int count = _width * _height;
List<bool> list = Enumerable.Repeat(false, count).ToList();
for (int y = 0; y < _height; y++)
{
for (int x = 0; x < _width; x++)
{
Vector2 p = new Vector2(x, y);
int index = PathFinder.Instance.TileIndex(p);
list[index] = Utility.RandomPercent(chance);
}
}
for (int i = 0; i < steps; i++)
{
var temp = Enumerable.Repeat(false, count).ToList();
for (int y = 0; y < _height; y++)
{
for (int x = 0; x < _width; x++)
{
Vector2 p = new Vector2(x, y);
int index = PathFinder.Instance.TileIndex(p);
if (index == -1) Debug.Log(index);
int adjacent = GetAdjacentCount(list, p);
bool set = list[index];
if (set)
{
if (adjacent < death)
set = false;
}
else
{
if (adjacent > birth)
set = true;
}
temp[index] = set;
}
}
list = temp;
}
if ((steps > 0) && Utility.RandomBool())
RemoveSmall(list);
return list;
}