从中心十六进制中查找相邻的十六进制,而不是从分组的十六进制外部

时间:2018-03-17 10:55:29

标签: c# unity3d math

我正在为地图制作随机十六进制生成的几个教程。我目前正试图通过获取围绕该特定十六进制的其他六边形来在地图上基于单个十六进制随机生成大陆。

这是我将所有相邻的十六进制放入数组的代码:

    public HexCell[] GetHexWithinRange (HexCell centerHex, int range)
{
    List<HexCell> hexWithinRange = new List<HexCell>();
    int x = centerHex.coordinates.X;
    int y = centerHex.coordinates.Y;
    int z = centerHex.coordinates.Z;

    int sequence = 0;
    for (int dy = -range; dy < range + 1; dy++) 
    {
        for (int dz = -range; dz < range + 1; dz++)
        {
            for (int dx = -range; dx < range + 1; dx++)
            {
                HexCell neighborHex = GetCellFromCoord(x + (float)dx,
                 y + (float)dy, z + (float)dz);

                if (neighborHex == null)
                { continue; }
                else
                {
                    neighborHex.sequenceCheck = sequence++;
                    hexWithinRange.Add(neighborHex);
                }
            }
        }
    }
    return hexWithinRange.ToArray();
}

Perfectly hexagonal shaped continent

虽然代码返回一个形状完美的大陆,但是它将其他六角形从外圈对角地放入中心十六进制:

Sequence when the code is putting the neighboring hex into array

我真正希望它做的是从大陆内部获取相邻的十六进制并从那里移出,直到达到预期的半径,如下所示:

Sequence how I want the code to put the neighboring hex into array

我尝试使用公式将相邻的六边形逐个环放在数组中。但是我希望将半径从中心十六进制变为变量。我怎么做?

2 个答案:

答案 0 :(得分:1)

请注意,您希望按半径遍历每个“轴”。

例如,如果从半径== 1的[36,-57,21]开始,沿X移动1 Hex,沿Y移动1,沿z移动1,然后沿X,Y和Z向后移动,然后回到[36,-57,21]。

当Radius == 2时,它相同,只有你每个轴行进2次。等等。

所以,我觉得这样的事情会起作用(如果你的Vector3十六进制表示是正确的,并且已经定义了附加内容)

var center = centerHex.coordinates;
var offset = new Vector3(0, 0, 0);

int radius = 0;
for(radius = 0; radius < 4 radius ++){
  for(i = 0; i < radius; i++){
    AddCell(center + offset);
    offset.X++;
  }

  for(i = 0; i < radius; i++){
    AddCell(center + offset);
    offset.Y--;
  }

  for(i = 0; i < radius; i++){
    AddCell(center + offset);
    offset.Z--;
  }

  for(i = 0; i < radius; i++){
    AddCell(center + offset);
    offset.X--;
  }

  for(i = 0; i < radius; i++){
    AddCell(center + offset);
    offset.Y++;
  }

  for(i = 0; i < radius; i++){
    AddCell(center + offset);
    offset.Z++;
  }

  offset.Z++;

}

}

答案 1 :(得分:0)

我明白了。我没有使用范围作为循环的限制,而是在原始范围内创建了增量范围。为了避免最初的问题再次出现,我在循环检查列表/数组中的重复单元格之前,先添加它当前所在的单元格。

    for (int curRange = 1; curRange < range + 1; curRange++)
    {
        for (int dy = -curRange; dy < curRange + 1; dy++)
        {
            for (int dz = -curRange; dz < curRange + 1; dz++)
            {
                for (int dx = -curRange; dx < curRange + 1; dx++)
                {
                    HexCell neighborHex = GetCellFromCoord(x + (float)dx, y + (float)dy, z + (float)dz);

                    if (neighborHex == null)
                    {
                        continue;
                    }
                    else if (x == neighborHex.coordinates.X && 
                        y == neighborHex.coordinates.Y && 
                        z == neighborHex.coordinates.Z)
                    {
                        continue;
                    }
                    else
                    {
                        if (hexWithinRange.Contains(neighborHex))
                        {
                            continue;
                        }
                        else
                        {
                            hexWithinRange.Add(neighborHex);
                        }
                    }
                }
            }
        }
    }