等距屏幕到地图的转换

5
我试图找出如何在我有“坡道”和+1高度瓷砖(见下图)时,在鼠标下获取正确的“活动”瓷砖。
当我的世界是平的时候,一切都没有问题。一旦我添加一个高度为+1的瓷砖,再加上一个返回到+0的坡道,我的屏幕->地图例程仍然看起来像一切都是“平的”。
在上面的图片中,绿色的“坡道”是我想要渲染和计算鼠标->地图的实际瓷砖,但你看到“下面”的蓝色瓷砖是被计算的区域。所以,如果你把鼠标移到任何深绿色区域,它会认为你在另一个瓷砖上。
这是我的地图呈现(非常简单)。
canvas.width = canvas.width; // cheap clear in firefox 3.6, does not work in other browsers
for(i=0;i<map_y;i++){
    for(j=0;j<map_x;j++){
        var xpos = (i-j)*tile_h + current_x;
        var ypos = (i+j)*tile_h/2+ current_y;

      context.beginPath();
      context.moveTo(xpos, ypos+(tile_h/2));
      context.lineTo(xpos+(tile_w/2), ypos);
      context.lineTo(xpos+(tile_w), ypos+(tile_h/2));
      context.lineTo(xpos+(tile_w/2), ypos+(tile_h));
      context.fill();

    }
}    

以下是我的鼠标 -> 映射程序:

ymouse=( (2*(ev.pageY-canvas.offsetTop-current_y)-ev.pageX+canvas.offsetLeft+current_x)/2 );
xmouse=( ev.pageX+ymouse-current_x-(tile_w/2)-canvas.offsetLeft );
ymouse=Math.round(ymouse/tile_h);
xmouse=Math.round(xmouse/(tile_w/2));

current_tile=[xmouse,ymouse];

我有一种感觉,我将不得不重新开始实现一个基于世界地图系统而非简单的屏幕 -> 地图程序。谢谢。
2个回答

2
您的假设是正确的。为了对世界几何图形进行“拾取”,您的程序需要了解世界(而不仅仅是基本级别的瓷砖配置)。也就是说,如果没有关于当前选定瓷砖附近瓷砖高度的概念(通过您当前的算法),就无法确定是否应该通过挑选光线拦截相邻的瓷砖(或者更远的瓷砖,具体取决于允许的高度)。
您已经得到了挑选光线的最终可能点。剩下的是定义光线在世界空间中的其余部分,并检查光线与世界几何图形的交点。

2
如果您的视角始终保持在45度且始终来自同一方向(如图片所示),您的鼠标->地图例程可以使用类似以下算法的方法:
  1. 像您目前正在做的那样计算瓦片的i,j值(即xmouse,ymouse的最终值)
  2. 查找i,j处瓦片的高度和角度
  3. 考虑到高度和角度,此瓦片是否与拾取光线相交?如果是,则设置lasti,lastj = i,j
  4. 对i,j进行对角线方向上的增量/减量
  5. 我们已经走出了地图边缘吗?如果是,则返回lasti,lastj。否则回到步骤2。
根据瓦片的最大高度,您可能只需要检查2个瓦片,而不必一直检查到地图的边缘。
第3步是棘手的部分,这取决于您的世界几何形状。画一些三角形,您应该能够理解它。或者您可以尝试查看intersect_quadrilateral_ray() here函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接