【问题标题】:Get coordinates of adjacent hexagon tiles in a coordinate system获取坐标系中相邻六边形图块的坐标
【发布时间】:2017-09-01 20:59:32
【问题描述】:

我想突出显示放置在六边形瓷砖系统中的单位范围内的瓷砖。例如,如果我在 6|5 上放置一个 range=2 的单位,我想突出显示 5|4、6|4、7|4、7|5、6|6、5|5、4|5、4| 4、5|3 等等...

如何根据原点坐标和范围计算这些坐标?目前我使用许多 if 子句来检查每一种可能性:

if (gameField[x, y].IsHighlighted && gameField[x, y].DeployedUnit != null)
{
    if (gameField[x, y].DeployedUnit.AttackRange > 0)
    {
        if (x % 2 == 0)
        {
            if (x > 0 && y > 0)
                 {
                      gameField[x - 1, y - 1].IsGreenRange = true;
                 }
                 if (x > 0)
                 {
                      gameField[x - 1, y].IsGreenRange = true;
                 }
                 if (y < height - 1)
                 {
                      gameField[x, y + 1].IsGreenRange = true;
                 }
                 if (x < length - 1)
                 {
                      gameField[x + 1, y].IsGreenRange = true;
                 }
                 if (x < length - 1 && y > 0)
                 {
                      gameField[x + 1, y - 1].IsGreenRange = true;
                 }
                 if (y > 0)
                 {
                      gameField[x, y - 1].IsGreenRange = true;
                 }
        }
        else
        {
                 [...]
        }
    }
}

但是随着范围的增加,复杂性也在增加……必须有更好的方法。有什么想法吗?

【问题讨论】:

    标签: c# monogame hexagonal-tiles


    【解决方案1】:

    递归。就像你可以通过移动来说明你可以到达哪些格子一样。

    【讨论】:

    • 另外,这篇文章可能值得一看:Naidamast
    【解决方案2】:

    多亏了 MartinB,我尝试了递归方法,它就像一个魅力。 :)

    private void HighlightRange(int originX, int originY, int range, bool greenRange = true)
            {
                if (range > 0)
                {
                    List<Tuple<int, int>> hexCoordinates = new List<Tuple<int, int>>();
                    if (originX % 2 == 0)
                    {
                        hexCoordinates.Add(new Tuple<int, int>(originX, originY - 1));
                        hexCoordinates.Add(new Tuple<int, int>(originX - 1, originY - 1));
                        hexCoordinates.Add(new Tuple<int, int>(originX - 1, originY));
                        hexCoordinates.Add(new Tuple<int, int>(originX, originY + 1));
                        hexCoordinates.Add(new Tuple<int, int>(originX + 1, originY));
                        hexCoordinates.Add(new Tuple<int, int>(originX + 1, originY - 1));
                    }
                    else
                    {
                        hexCoordinates.Add(new Tuple<int, int>(originX, originY - 1));
                        hexCoordinates.Add(new Tuple<int, int>(originX - 1, originY));
                        hexCoordinates.Add(new Tuple<int, int>(originX - 1, originY + 1));
                        hexCoordinates.Add(new Tuple<int, int>(originX, originY + 1));
                        hexCoordinates.Add(new Tuple<int, int>(originX + 1, originY + 1));
                        hexCoordinates.Add(new Tuple<int, int>(originX + 1, originY));
                    }
                    hexCoordinates.RemoveAll(t => (t.Item1 < 0 || t.Item1 >= length || t.Item2 < 0 || t.Item2 >= height));
    
                    while (hexCoordinates.Count > 0)
                    {
                        if (range > 1)
                        {
                            HighlightRange(hexCoordinates[0].Item1, hexCoordinates[0].Item2, range - 1, greenRange);
                        }
                        if (greenRange)
                        {
                            gameField[hexCoordinates[0].Item1, hexCoordinates[0].Item2].IsGreenRange = true;
                        }
                        else
                        {
                            gameField[hexCoordinates[0].Item1, hexCoordinates[0].Item2].IsRedRange = true;
                        }
                        hexCoordinates.RemoveAt(0);
                    }
                }
                else
                {
                    return;
                }
            }
    

    【讨论】: