我有一个存储所有六边形的二维数组。它是一个 Hexagon
对象数组,使用 2 个整数进行索引。
我想交换 3 个六边形,就像图中所示的那样。
任何人都可以帮助我制定应该完成这项工作的算法吗?
谢谢!
这是创建六边形的函数。
public void CreateGrid(int gridWidth, int gridHeight)
{
for (int y = 0; y < gridHeight; y++)
{
for (int x = 0; x < gridWidth; x++)
{
GameObject Hexagon = Instantiate(HexagonPre,
Vector2.zero,
Quaternion.identity,
HexGrid);
Vector2 gridPos = new Vector2(x, y);
Hexagon.transform.position = CalcWorldPos(gridPos);
Hexagon.transform.name = "X: " + x + " | Y: " + y;
}
}
}
Vector2 CalcWorldPos(Vector2 gridPos)
{
float offset = 0;
if(gridPos.y %2 != 0)
offset = hexWidth / 2f;
float x = startPos.x + gridPos.x * hexWidth + offset;
float y = startPos.y - gridPos.y * hexHeight * 0.75f;
return new Vector2(x, y);
}
好吧,我分享了游戏的样子。我点击游戏中的某个地方。游戏会在我点击的地方找到 3 个最近的六边形。然后我更改这 3 个六边形的位置。 (我已经这样做了)。但不知何故,我需要我的数组知道这 3 个六边形彼此交换了。请注意,这可能是任意 3 个六边形。所以我们需要一个算法来让任意 3 个六边形交换它们在数组中的位置。
显示我已有内容的视频:youtube.com/watch?v=fVvQd47OswQ&feature=youtu.be
最佳答案
如果您已经有了 3 个六边形的坐标,那么您可以确定哪个六边形具有唯一的 Y 坐标,并确定另外两个六边形中哪个在右侧,哪个在左侧:
Vector2Int hexagonACoord;
Vector2Int hexagonBCoord;
Vector2Int hexagonCCoord;
Vector2Int loneHexagonCoord;
Vector2Int leftHexagonCoord;
Vector2Int rightHexagonCoord;
if (hexagonACoord.y != hexagonBCoord.y && hexagonACoord.y != hexagonCCoord.y)
{
loneHexagonCoord = hexagonACoord;
leftHexagonCoord = hexagonBCoord;
rightHexagonCoord = hexagonCCoord;
}
else if (hexagonBCoord.y != hexagonCCoord.y && hexagonBCoord.y != hexagonACoord.y)
{
loneHexagonCoord = hexagonBCoord;
leftHexagonCoord = hexagonACoord;
rightHexagonCoord = hexagonCCoord;
}
else
{
loneHexagonCoord = hexagonCCoord;
leftHexagonCoord = hexagonACoord;
rightHexagonCoord = hexagonBCoord;
}
if (leftHexagonCoord.x > rightHexagonCoord.x)
{
Vector2Int tempCoord = leftHexagonCoord;
leftHexagonCoord = rightHexagonCoord;
rightHexagonCoord = tempCoord;
}
然后根据单独的六角形是否在顶部,我们可以确定旋转的方向以便顺时针旋转:
if (loneHexagonCoord.y > leftHexagonCoord.y)
{
Hexagon tempHex = hexagonsArray[loneHexagonCoord.x, loneHexagonCoord.y];
hexagonsArray[loneHexagonCoord.x, loneHexagonCoord.y] =
hexagonsArray[rightHexagonCoord.x, rightHexagonCoord.y];
hexagonsArray[rightHexagonCoord.x, rightHexagonCoord.y] =
hexagonsArray[leftHexagonCoord.x, leftHexagonCoord.y];
hexagonsArray[leftHexagonCoord.x, leftHexagonCoord.y] = tempHex;
}
else
{
Hexagon tempHex = hexagonsArray[loneHexagonCoord.x, loneHexagonCoord.y];
hexagonsArray[loneHexagonCoord.x, loneHexagonCoord.y] =
hexagonsArray[leftHexagonCoord.x, leftHexagonCoord.y];
hexagonsArray[leftHexagonCoord.x, leftHexagonCoord.y] =
hexagonsArray[rightHexagonCoord.x, rightHexagonCoord.y];
hexagonsArray[rightHexagonCoord.x, rightHexagonCoord.y] = tempHex;
}
然后,更新其 HexCooperatives
组件的位置:
hexagonsArray[loneHexagonCoord.x, loneHexagonCoord.y]
.GetComponent<HexCoordinates>().Coordinates = new Vector2Int(
loneHexagonCoord.x, loneHexagonCoord.y);
hexagonsArray[leftHexagonCoord.x, leftHexagonCoord.y]
.GetComponent<HexCoordinates>().Coordinates = new Vector2Int(
leftHexagonCoord.x, leftHexagonCoord.y);
hexagonsArray[rightHexagonCoord.x, rightHexagonCoord.y]
.GetComponent<HexCoordinates>().Coordinates = new Vector2Int(
rightHexagonCoord.x, rightHexagonCoord.y);
当我在下面回答时,没有迹象表明选择 3 个六边形的逻辑已经完成。我将保留这个,因为它回答了一个非常相关的问题:
好吧,我们可以将六边形网格的交点分成三角形,并将它们配对成平行四边形,如下所示:
鼠标位置(在世界空间中)所在的平行四边形的 Y 坐标很简单:
float pgYCoord = Mathf.Floor((startPos.y - mousePos.y) / (hexHeight * 0.75f));
鼠标所在的平行四边形的X坐标比较复杂:
float xOffsetAtMouseY = startPos.x + hexWidth / 2f * (startPos.y - mousePos.y) / (hexHeight * 0.75f)
float pgXCoord = Mathf.Floor((mousePos.x - xOffsetAtMouseY) / hexWidth);
然后判断鼠标是否在该平行四边形的A或B三角形中:
float vertDistFromTopEdge = Mathf.Repeat(startPos.y-mousePos.y, hexHeight * 0.75f );
float horizDistFromTopLeftCorner = mousePos.x - startPos.x - pgXCoord*hexWidth - pgYCoord * hexWidth / 2f;
bool isInATriangle =
vertDistFromTopEdge
< 1.5f * hexHeight
- horizDistFromTopLeftCorner * (hexHeight * 0.75) / (hexWidth / 2f);
然后根据我们是否处于 A 三角形中,我们可以按顺时针顺序确定六边形的坐标:
Vector2Int hexagonCoordA;
Vector2Int hexagonCoordB;
Vector2Int hexagonCoordC;
if (isInATriangle)
{
hexagonCoordA = new Vector2Int(pgXCoord, pgYCoord);
hexagonCoordB = new Vector2Int(pgXCoord+1, pgYCoord);
hexagonCoordC = new Vector2Int(pgXCoord, pgYCoord+1);
}
else
{
hexagonCoordA = new Vector2Int(pgXCoord, pgYCoord+1);
hexagonCoordB = new Vector2Int(pgXCoord+1, pgYCoord);
hexagonCoordC = new Vector2Int(pgXCoord+1, pgYCoord+1);
}
// every 2 rows, the pg x coord grows 1 additional higher than the hex x coord
hexagonCoordA.x += Mathf.Floor(0.5f*hexagonCoordA.y);
hexagonCoordB.x += Mathf.Floor(0.5f*hexagonCoordB.y);
hexagonCoordC.x += Mathf.Floor(0.5f*hexagonCoordC.y)
如果任何 hexagonCoord 变量具有无效索引(在单独的问题中更合适),则鼠标当前不在 3 个六边形的交集上。否则,您可以交换 3 个六边形。
int arrayXSize = hexagonArray.GetLength(0);
int arrayYSize = hexagonArray.GetLength(1);
if ( hexagonCoordA.x >= 0 && hexagonCoordA.x < arrayXSize
&& hexagonCoordA.y >= 0 && hexagonCoordA.y < arrayYSize
&& hexagonCoordB.x >= 0 && hexagonCoordB.x < arrayXSize
&& hexagonCoordB.y >= 0 && hexagonCoordB.y < arrayYSize
&& hexagonCoordC.x >= 0 && hexagonCoordC.x < arrayXSize
&& hexagonCoordC.y >= 0 && hexagonCoordC.y < arrayYSize)
{
Hexagon tempHex = hexagonsArray[hexagonCoordA.x, hexagonCoordA.y];
hexagonsArray[hexagonCoordA.x, hexagonCoordA.y] =
hexagonsArray[hexagonCoordC.x, hexagonCoordC.y];
hexagonsArray[hexagonCoordC.x, hexagonCoordC.y] =
hexagonsArray[hexagonCoordB.x, hexagonCoordB.y];
hexagonsArray[hexagonCoordB.x, hexagonCoordB.y] = tempHex;
Vector3 temp = hexagonA.transform.position;
hexagonA.transform.position = hexagonB.transform.position;
hexagonB.transform.position = hexagonC.transform.position;
hexagonC.transform.position = temp;
}
关于c# - 交换 3 个六边形邻居的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57714779/