首页 > 解决方案 > 交换 3 个六边形邻居的参考

问题描述

我有一个存储所有六边形的二维数组。它是一个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

标签: c#unity3d

解决方案


如果你已经有了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;
}

然后,更新其HexCoordinates组件的位置:

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;

}

推荐阅读