我认为Michael Kristofik的答案是正确的,尤其是提到Amit Patel的网站时,但我想分享一下我对十六进制网格的新手方法。
这段代码取自一个我不感兴趣的项目,并放弃了用JavaScript编写的项目,但是将鼠标放置在十六进制图块上的效果很好。我使用* 此GameDev文章 *作为参考。作者从该网站上获得了这张图片,该图片展示了如何在数学上表示所有十六进制的边和位置。
在我的渲染类中,我在一个方法中定义了此方法,该方法允许我设置所需的十六进制边长。之所以显示此处,是因为这些值中的某些已在像素中引用为十六进制坐标代码。
this.s = Side; //Side length
this.h = Math.floor(Math.sin(30 * Math.PI / 180) * this.s);
this.r = Math.floor(Math.cos(30 * Math.PI / 180) * this.s);
this.HEXWIDTH = 2 * this.r;
this.HEXHEIGHT = this.h + this.s;
this.HEXHEIGHT_CENTER = this.h + Math.floor(this.s / 2);
在鼠标输入类中,我创建了一个方法,该方法接受屏幕的x和y坐标,并返回一个像素位于其中的具有十六进制坐标的对象。*请注意,我有一个伪造的“相机”,所以渲染位置的偏移也包括在内。
ConvertToHexCoords:function (xpixel, ypixel) {
var xSection = Math.floor(xpixel / ( this.Renderer.HEXWIDTH )),
ySection = Math.floor(ypixel / ( this.Renderer.HEXHEIGHT )),
xSectionPixel = Math.floor(xpixel % ( this.Renderer.HEXWIDTH )),
ySectionPixel = Math.floor(ypixel % ( this.Renderer.HEXHEIGHT )),
m = this.Renderer.h / this.Renderer.r, //slope of Hex points
ArrayX = xSection,
ArrayY = ySection,
SectionType = 'A';
if (ySection % 2 == 0) {
/******************
* http://www.gamedev.net/page/resources/_/technical/game-programming/coordinates-in-hexagon-based-tile-maps-r1800
* Type A Section
*************
* * *
* * * *
* * * *
* * * *
*************
* If the pixel position in question lies within the big bottom area the array coordinate of the
* tile is the same as the coordinate of our section.
* If the position lies within the top left edge we have to subtract one from the horizontal (x)
* and the vertical (y) component of our section coordinate.
* If the position lies within the top right edge we reduce only the vertical component.
******************/
if (ySectionPixel < (this.Renderer.h - xSectionPixel * m)) {// left Edge
ArrayY = ySection - 1;
ArrayX = xSection - 1;
} else if (ySectionPixel < (-this.Renderer.h + xSectionPixel * m)) {// right Edge
ArrayY = ySection - 1;
ArrayX = xSection;
}
} else {
/******************
* Type B section
*********
* * * *
* * *
* * *
*********
* If the pixel position in question lies within the right area the array coordinate of the
* tile is the same as the coordinate of our section.
* If the position lies within the left area we have to subtract one from the horizontal (x) component
* of our section coordinate.
* If the position lies within the top area we have to subtract one from the vertical (y) component.
******************/
SectionType = 'B';
if (xSectionPixel >= this.Renderer.r) {//Right side
if (ySectionPixel < (2 * this.Renderer.h - xSectionPixel * m)) {
ArrayY = ySection - 1;
ArrayX = xSection;
} else {
ArrayY = ySection;
ArrayX = xSection;
}
} else {//Left side
if (ySectionPixel < ( xSectionPixel * m)) {
ArrayY = ySection - 1;
ArrayX = xSection;
} else {
ArrayY = ySection;
ArrayX = xSection - 1;
}
}
}
return {
x:ArrayX + this.Main.DrawPosition.x, //Draw position is the "camera" offset
y:ArrayY + this.Main.DrawPosition.y
};
},
最后,这是打开渲染调试的项目的屏幕截图。它显示了红线,代码在其中检查了TypeA和TypeB单元以及十六进制坐标和单元轮廓,
希望对您有所帮助。