c# - 交换 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
解决方案
如果你已经有了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;
}
推荐阅读
- python - 表单问题 - 设置初始值
- gnuplot - 在 gnuplot 的 x 轴下方放置更多文本
- ios - 如何从 Swift 中的 .m3u8 格式视频 url 获取缩略图?
- python - sklearn.exceptions.NotFittedError: Estimator not fit, 在利用模型之前调用“fit”
- vba - 通过 VBA 删除多个列
- javascript - 过滤器工具栏不适用于自定义列,即我在列中使用了格式化程序并且过滤器不起作用
- python-3.x - 在 pycharm 中导入“维基百科模块”时出错
- java - 如何使用 Java 中的改造从 Google 附近的搜索 API 检索图像 url
- visual-c++ - 为什么 CreateRemoteThread 导致注入目标崩溃
- ruby-on-rails - 在 Rails 公寓中使用 config.excluded 模型时,UsersRole 表无法正常工作