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];

我有一种感觉,我必须重新开始并实现一个基于世界的地图系统,而不是一个简单的屏幕 -> 地图例程。

谢谢。

4

2 回答 2

2

你的假设是正确的。为了“挑选”世界几何,您的例程需要了解世界(而不仅仅是基础级别的图块配置)。也就是说,如果没有任何关于当前选择的瓷砖附近的瓷砖高度的概念(通过您当前的算法),就无法确定相邻的瓷砖(或者更远的瓷砖,取决于允许的高度)是否应该是被采光射线拦截。

你已经得到了你的拾取射线的最终可能点。剩下的就是在世界空间中定义光线的其余部分,并检查该光线是否与世界几何体相交。

于 2010-09-13T16:41:31.717 回答
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()

于 2010-09-14T22:51:50.973 回答