c# - 交换 3 个六边形邻居的引用

标签 c# unity-game-engine

我有一个存储所有六边形的二维数组。它是一个 Hexagon 对象数组,使用 2 个整数进行索引。

我想交换 3 个六边形,就像图中所示的那样。

任何人都可以帮助我制定应该完成这项工作的算法吗?

谢谢!

Example

这是创建六边形的函数。

    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 个六边形的逻辑已经完成。我将保留这个,因为它回答了一个非常相关的问题:


好吧,我们可以将六边形网格的交点分成三角形,并将它们配对成平行四边形,如下所示:

enter image description here

鼠标位置(在世界空间中)所在的平行四边形的 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/

相关文章:

java - Java SettableFuture 和 ListenableFuture 的 C# 等价物是什么?

c# - 如何检查windowsstore应用程序中是否存在文件

c# - 无法添加服务引用

c# - 是否可以在不使用任何实际电子邮件帐户的情况下以编程方式发送电子邮件

unity-game-engine - AppendStructuredBuffer 计数与我所做的附加不匹配(Unity3D、HLSL)

android - 实现成就和排行榜 Unity、Android 时出现的问题 - Google-Play-Games

c# - File.WriteAllBytes 正在创建一个 0 字节文件

c# - 在 Unity 中使用自己的碰撞器将圆形 Sprite 分割成彩色 block

android - 在Unity中打开SWF游戏

c# - 使用 Console.Beep .Net 播放语音词的声音