如何渲染十六进制网格

时间:2015-11-28 02:31:38

标签: java rendering hexagonal-tiles

我目前正致力于一款需要渲染六边形网格的游戏,以便为游戏提供场所。我正在使用偏移坐标将十六进制网格存储在内存中。当我尝试渲染网格时,我得到如下结果,其中六边形之间有空格。我希望hexes完美对齐,以便所有必要的都在完全相同的点,并且它们的线重叠并且在hexes之间没有空格

每个十六进制内的坐标代表十六进制的偏移坐标。 hex grid with extra space between the hexes

我使用下图中显示的距离(source)来决定渲染每个十六进制的位置。 hex grid with background rectangular grid showing distance between the centers of pointy-topped hexes

我能找到的唯一一个StackExchange问​​题解决了一个类似于here的问题。然而,它只讨论了存储格式的数据结构,而不是如何从所述结构中呈现它们。我试图按照here描述的那样渲染它们,但是,我得到了上面显示的错误结果。

以下是我的代码处理渲染的部分(应该很容易推断各种自定义方法的作用,如果有任何混淆请告诉我):

    @Override
public void paint(Graphics g){
    int quarterHexSize = 32; //using non static final member variables because I want to make this dynamically determine the largest size of the hexagons that will fit on the screen later
    int halfHexSize = quarterHexSize * 2;
    int hexSize = halfHexSize * 2;
    int cx, cy, renderX, renderY;

    g.setColor(Color.DARK_GRAY);
    g.fillRect(0, 0, getWidth(), getHeight());

    g.setColor(Color.WHITE);
    for(cx=0;cx<5;cx++){
        for(cy=0;cy<5;cy++){
            Hex hex = board.getHexAt(cx, cy);

            if(hex != null){
                renderX = cx * 2; //multiplying by 2 rather than using floats to represent half offset to simplify code and because IIRC integers are faster, I got the same error when using floats
                renderY = cy * 2;

                if(renderY % 4 != 0){
                    renderX++;
                }

                //converts the somewhat arbitrary units into the actual display size units using the values from the image in the question
                renderX *= hexSize;
                renderY *= quarterHexSize * 3f;

                //the numbers are divided by 2 to make up for the offset
                renderX /= 2;
                renderY /= 2;

                //64 is added to both dimensions to shift the grid inside the window
                renderX += 64;
                renderY += 64;

                drawHex(new RenderPoint(renderX, renderY), halfHexSize, g);
                g.drawString(cx + ", " + cy, renderX, renderY);
            }
        }
    }
}

private void drawHex(RenderPoint center, int hexSize, Graphics g){
    drawHexLine(center, hexSize, 0, 1, g);
    drawHexLine(center, hexSize, 1, 2,  g);
    drawHexLine(center, hexSize, 2, 3,  g);
    drawHexLine(center, hexSize, 3, 4,  g);
    drawHexLine(center, hexSize, 4, 5,  g);
    drawHexLine(center, hexSize, 5, 0,  g);
}

private void drawHexLine(RenderPoint center, int hexSize, int firstCornerNum, int secondCornerNum, Graphics g){
    RenderPoint firstCornerNumHexPoint = getHexCorner(center, hexSize, firstCornerNum);
    RenderPoint secondCornerNumHexPoint = getHexCorner(center, hexSize, secondCornerNum);

    g.drawLine(
            firstCornerNumHexPoint.getX(), firstCornerNumHexPoint.getY(),
            secondCornerNumHexPoint.getX(), secondCornerNumHexPoint.getY()
    );

    //g.drawString(String.valueOf(firstCornerNum), firstCornerNumHexPoint.getX(), firstCornerNumHexPoint.getY());
}

private RenderPoint getHexCorner(RenderPoint center, int hexSize, int cornerNum){
    return RenderPoint.doublesToInts( //simply rounds the provided doubles and creates a RenderPoint object with these new rounded values
            center.getX() + hexSize * Math.sin(cornerNum * 60 * 0.0174533), //decimal number converts from degrees to radians
            center.getY() + hexSize * Math.cos(cornerNum * 60 * 0.0174533)
    );
}

1 个答案:

答案 0 :(得分:0)

我已确定错误是什么。当我假设我在问题中发布的图表完全解释了六边形的位置时,我错过了webpage中的具体细节。

我已将变量renderX更改为:

renderX *= Math.round(HALF_SQRT_THREE * hexSize);

HALF_SQRT_THREE是我在变量中定义的常量,以避免每次渲染六边形时重新计算它。它定义为Math.sqrt(3)/2.0

以下是webpage

的引用
  

六边形的宽度是宽度= sqrt(3)/ 2 *高度。相邻六边形之间的水平距离是horiz = width。