等距屏幕到地图
我试图弄清楚当我有“斜坡”和+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];
我有一种感觉,我必须重新开始并实现一个基于世界的地图系统,而不是一个简单的屏幕 ->地图例程。
谢谢。
I'm trying to figure out how I can get the correct "active" tile under the mouse when I have "ramp" and +1 height tiles (see picture below).
When my world is flat, everything works no problem. Once I add a tile with a height of say +1, along with a ramp going back to +0, my screen -> map routine is still looking as if everything is "flat".
In the picture above, the green "ramp" is the real tile I want to render and calculate mouse -> map, however the blue tile you see "below" it is the area which gets calculated. So if you move your mouse into any of the dark green areas, it thinks you're on another tile.
Here is my map render (very simple)
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();
}
}
And here is my mouse -> map routine:
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];
I have a feeling I'll have to start over and implement a world based map system rather than a simple screen -> map routine.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的假设是正确的。为了根据世界几何形状“挑选”,您的例程需要了解世界(而不仅仅是基础级别的图块配置)。也就是说,如果没有任何关于当前选取的图块附近的图块高度(通过您当前的算法)的概念,则无法确定是否应将相邻图块(或更远的图块,取决于允许的高度)被拾取射线拦截。
您已经获得了拾取射线的最终可能点。剩下的就是在世界空间中定义光线的其余部分,并检查该光线与世界几何体的相交。
Your assumption is correct. In order to "pick" against world geometry, your routine needs to be aware of the world (and not just the base-level tile configuration). That is, without any concept of the height of the tiles near the one that is currently picked (by your current algorithm), there's no way to determine whether a neighboring tile (or one even further away, depending on the permitted height) should be intercepted by picking ray.
You've got the final possible point of your picking ray, already. What remains is to define the remainder of the ray, in world-space, and to check that ray for intersections with world geometry.
如果如图所示,您的视角始终为 45 度且始终来自同一方向,则您的鼠标 ->地图例程可以使用类似于以下的算法:
根据图块的最大高度,您可能只需检查 2 个图块,而不是一直检查到地图边缘。
3 是棘手的部分,取决于你的世界几何形状。画一些三角形,你应该能够弄清楚。或者您可以尝试在intersect_quadrilateral_ray() 这里查看函数。
If, like the picture, your view angle is always 45 degrees and always from the same direction, your mouse -> map routine could use an algorithm something like:
Depending on the maximum height of a tile, you might have to check only 2 tiles, rather than going all the way to the edge of the map.
3 is the tricky part, and depends on your world geometry. Draw some triangles and you should be able to figure it out. Or you might try looking at the function intersect_quadrilateral_ray() here.