使用canvas context.arc()计算Reus样式世界上的图块ID

我需要为我的游戏提供一些math帮助。

我正在使用Javascript和Canvas标签来创建一个圆形的世界,想想God Finger和Reus。 我的游戏的当前版本在这里: http : //lazyeels-sandbox.appspot.com/

问题是
canvas画出顺时针方向90度开始的弧(或圆)。 看到一个示例图像。

我的游戏将世界拆分为细分(瓷砖)。 世界上有10个瓷砖长度,我想计算鼠标hover在哪个瓷砖上,这样玩家可以添加建筑物或调整瓷砖的高度。

所以我需要计算偏移量并从鼠标角度中扣除(弧度或度数很好)。 不过,我似乎无法做到。 我知道理论上我应该做以下事情:

  • 计算鼠标的角度。
  • 通过除以分段大小来计算分块(按照常规分块图即y轴/分块宽度)。
  • 将角度的偏移量移到圆顶部的0度,而不是顺时针旋转90度)。
  • 扣除偏移量以获得新的瓷砖位置。

这是我正在使用的主要function;

var getMouseAngle = function(mouse){ var world_length = 10; var segment = (Math.PI * 2)/world_length; // Get the distance var dx = mouse.x - ((canvas.width * 0.5) - Game.camera.xScroll); var dy = mouse.y - ((canvas.height - Game.camera.yScroll) * Game.camera.zoom); // calculate the angle var arctan = Math.atan2(dy, dx); // Reset the angle if it is a negative value var angle = dy < 0 ? (Math.PI * 2) + arctan: arctan; // perhaps this is where I need to apply the offset. // Calculate the tile var orig_tile = angle/segment; // Calculate the offset var offset_tile = ((Math.PI * 3/2)/segment); // calculate offset clockwise = 270 degrees to the top of the circle (where the player sits). var tile = (orig_tile - offset_tile) // This is soooooo wrong return { dx: dx, dy: dy, degrees: (angle * 180/Math.PI).toFixed(2), radian: angle.toFixed(2) tile: Math.floor(tile), }; 

玩家瓦片function比较容易:

 Player.getTile = function(rotation){ var tile = Math.floor(rotation/Game.level.segment); if(rotation > 0){ tile = Math.abs((Game.level.world.length - tile)-1); } else { tile = Math.abs(tile)-1; } if(rotation == 0){ tile = 0; } return tile; }; 

有没有人知道我在计算错误的地方,即在计算瓦片之前应该如何以及何时应用偏移量 – 角度?

我没有显示我尝试的其他排列,如从原始角度减去偏移量,所有这些导致错误的瓷砖ID被返回。

我知道它应该是一个类似于玩家function的过程,即在计算中使用word_length。

Let N be the number of slices:

(alpha + beta) * N / (2 * PI)

在这里输入图像说明

*请注意, alpha是圆的旋转量Clock-Wise所以如果你的alpha代表旋转Counter-Clock-Wise,你需要减去它。

@ arthur-wulf-white感谢您对此问题的帮助。 有了这个讨论真的有帮助。 我认为它现在可以工作,但是这涉及到一些黑客行为,所以我对代码解决scheme不太满意,但是在这里。

 Level.prototype.getMouseAngle = function(mouse){ // Calculate the arctan between the mouse and the level x and y at the world center. var dx = mouse.x - (this.x - Game.camera.xScroll); var dy = mouse.y - ((this.y - Game.camera.yScroll) * Game.camera.zoom); var arctan = Math.atan2(dy, dx); // Reset angle to 0 on full rotation if(dy < 0){ angle = (Math.PI * 2) + arctan; } else { angle = arctan; } // Deduct world rotation angle -= this.rotation; // Get original tile position offset tile position and calculate final tile. // NB segment = (Math.PI * 2)/this.world.length. var orig_tile = angle/this.segment; var offset_tile = this.offset/this.segment; var final_tile = Math.floor(offset_tile - orig_tile); // Adjust tile according to offset. var tile = final_tile; if (tile < 0){ tile = (tile + this.world.length); } if(tile > 0){ tile = Math.abs((this.world.length-1) - tile); } if(this.world.length + final_tile == this.world.length){ tile = this.world.length - 1; } return {dx: dx, dy: dy, degrees: (angle * 180/Math.PI).toFixed(2), tile: Math.floor(tile), radian: angle.toFixed(2)}; }; 

如果你看到更好的解决scheme,那么我全部都是耳朵,同时再次感谢你解决我的问题所付出的所有努力,如果我的游戏成为了一件事情,我会给你很大的信心。 😉