【发布时间】:2016-03-28 14:29:30
【问题描述】:
我最初使用“Tile”的二维数组来存储程序生成的地图及其各种内容。
每个图块都包含一个相邻列表,它允许每个图块知道哪些顶点最靠近它,在 8 个不同的边上接触它(直接相邻和对角相邻)。
总体思路取自 Amit 的多边形地图生成,但我试图通过使用网格设置而不是 voronois 来简化它,但是我遇到的麻烦比我最初想象的要多。我目前的困境是在废弃 2d 数组时找出邻接关系。
这就是我在更改为列表之前的做法:
private void ConstructAdjacencyList() {
// Create Adjacency List
for (int x = 0; x < mapWidth; x++) {
for (int y = 0; y < mapHeight; y++) {
// Bool to find position of point
bool omitLeft = false; bool omitRight = false;
bool omitTop = false; bool omitBottom = false;
// Enable bools based on position, reset on each loop
if (x == 0)
omitLeft = true;
else if (x == mapWidth - 1)
omitRight = true;
if (y == 0)
omitTop = true;
else if (y == mapHeight - 1)
omitBottom = true;
// Add entries to list based on bool settings
if (!omitLeft) {
// Left center
islandMap[x,y].adjacent.Add(islandMap[x-1,y]);
if (!omitTop)
islandMap[x,y].adjacent.Add(islandMap[x-1,y-1]);
if (!omitBottom)
islandMap[x,y].adjacent.Add(islandMap[x-1,y+1]);
}
if (!omitTop) // Top Center
islandMap[x,y].adjacent.Add(islandMap[x,y-1]);
if (!omitBottom) // Bottom Center
islandMap[x,y].adjacent.Add(islandMap[x,y+1]);
if (!omitRight) {
// Right Center
islandMap[x,y].adjacent.Add(islandMap[x+1,y]);
if (!omitTop)
islandMap[x,y].adjacent.Add(islandMap[x+1,y-1]);
if (!omitBottom)
islandMap[x,y].adjacent.Add(islandMap[x+1,y+1]);
}
}
} // End Adjacency
Debug.Log ("Adjacencies Built");
}
x、y 值现在保存在 islandMap.point(存储 x 和 y 值的向量 2d,如下所示:)
public MapController() {
width = height = (int)Mathf.Sqrt (tileCount);
// Lists for points
var points = new List<Vector2>();
// Build a random set of points.
for (float x = 0; x < width; x++) {
for (float y = 0; y < height; y++) {
points.Add(new Vector2(x,y));
}
}
map = new Map (points, width, height, lakeTreshold);
}
地图本身目前有以下内容:
public class Map {
Func<Vector2, bool> inside; // Contains function to randomly seed area
bool needsMoreRandomness;
public List<Tile> islandMap; // Previously was Tile[,] islandMap
public int mapWidth { get; private set; } // Calculated as Sqrt(totalPoints)
public int mapHeight { get; private set; }
以及我目前坚持使用的其他方法,例如 ConstructAdjacencyList() 方法。
那么我怎样才能在不依赖数组定位的情况下继续构建周围点的邻接列表呢?我是否可以临时从数组中引用整个列表,在这个二维数组中放置对整个列表中每个图块的引用,设置邻接关系,然后删除数组而不丢失信息?我相信它只会使用引用,所以应该没问题...每个图块都包含一个索引来存储它的构建顺序,如下所示:
foreach (var point in points) {
var p = new Tile { index = islandMap.Count, point = point };
p.border = point.x == 0 || point.x == mapWidth || point.y == 0 || point.y == mapHeight;
islandMap.Add (p);
tileLookup[point] = p;
}
对不起,如果这太长了...我刚刚意识到它非常大 -.-
【问题讨论】:
-
有几种方法可以解决这个问题,但您的瓦片地图的大小可能会决定哪种解决方案更合适 - 您大约要处理多少瓦片?
-
嗨皮卡莱克,感谢您的回复。我将考虑输入最多 3000 点,目前徘徊在 300 点以下。老实说,有一次计算时间并不是什么大不了的事,只要它有效。
-
另外,我尝试做的事情如下:
Tile[,] tempArray = new Tile[mapWidth, mapHeight]; int count = 0; for (int x = 0; x < mapWidth; x++) { for (int y = 0; y < mapHeight; y++) { tempArray[x,y] = islandMap[count]; count++; } }试图将所有列表元素映射到二维数组,然后从那里开始计算逻辑,我还没有测试但是,无论这是否正确,因为我无法思考如何正确测试和调试此信息。 -
您可以将邻接存储为 Tile 对象模型的一部分。比如说,为每个图块存储一个 List
,其中包含对当前图块相邻的每个图块的引用(最多 8 个)。或者您可以将 2d x & y 坐标存储在您的 tile 模型中,然后从那里使用标准 2d 逻辑进行邻接。 -
@ManoDestra 这已经是它的设置方式了。我的问题与填充每个磁贴对象中存在的特定列表有关。检查我自己的答案以获得澄清。
标签: c# list procedural-generation