XNA – 制作二维六边形互相连接

嘿,所以我正在XNA上面做一个自上而下的2D策略游戏,而这些瓷砖是六边形的。 由于游戏机制,我不能拥有一个网格,所以一切都有自己的位置,并且每个图块对象都存储在一个列表中。 我想要做的是如果你把一块瓷砖贴在另一块瓷砖的旁边,它们会拼在一起成为一个对象。 我似乎无法弄清楚如何得到它应该捕捉的一面。

红色代表我想检查鼠标点击的不同部分(这些当然不是游戏中的实际纹理)。 白色代表如果你点击的区域,它不会让你放置一个瓷砖,因为它会在另一个之上。 我能想到的最接近的是在从中心到边缘被分成三角形的实际瓷砖周围有一个更大的六角形,但是我不知道如何去做。

我将把它移动到与Monogame的Windows Phone,我不认为手机是足够快,使某种事物,检查每个部门的颜色,所以我不认为它可以基于纹理。 我觉得这样做有一些相对简单的math,但我似乎无法弄清楚。 任何帮助将不胜感激。 谢谢!

比较鼠标右半径内的最近的hex形状的中心与鼠标本身之间的线,并获得它们之间的线相对于网格的水平轴的角度。 那么你可以使用像这样的function。

public Vector2 CalcHexPositionFromAngle(double angle, Vector2 point, double radius) { //assume the angle is in degrees and shed any numbers over 360 eg: 427 becomes 67 while(angle >= 360) { angle -= 360; } //This is a trick using the nature of truncation in most programming laguages int tempAngle = angle/60; //now we just multiply the number by 60 to bring it back up //to an increment of 60 degrees and add half that again to find an angle between //corners in the hex shape int angleOfPlacement = (tempAngle*60) +30; //assume the angle is in degrees (If angle is in radians forget this step) //sin uses radians not degrees. double newRadianAngle = angleOfPlacement*Math.PI(); //calculate the new position. double P_X = point.X + radius * Mathf.Cos(newRadianAngle); double p_Y = point.Y + radius * Mathf.Sin(newRadianAngle); return new Vector2(p_X,P_Y); } 

这应该给你新的位置,因为它是交给你的

您正在捕捉的原始hex与鼠标之间的角度(以度为单位)

vector2是您正在捕捉的始发hex的中心位置

和半径或(你的hex形状的相对面之间的距离的一半)

注意:此function需要度数,但可以很容易地适应弧度。

我可能要做的方法是在游戏循环开始之前的初始化阶段创建一个所有可能的hex中心位置的列表。 然后在游戏循环过程中,如果鼠标点击1.5瓦片半径(或任何你认为是approp的)的白色瓦片,只需迭代列表,find最接近的列表指向点击点。 如果鼠标点击比白色瓷砖中心更接近结果,则使用该结果作为要放置的新瓷砖的中心。 这一切都可以使用distaceSquared来避免一堆平方根。

更好的是,只需为每个可能邻居的中心位置存储6个相对偏移vector。 然后,当鼠标在白色的hex附近出现时,点击6次,然后find最接近的那个(mouseClick – whiteHexCenter)。 应该放置新的hex,使其中心位于(offsetResult + whiteHexCenter)。