使用多边形作为可点击区域,而不是矩形
Use polygons as clickable zones, instead of rectangles
我正在使用 allegro 库创建一个 2D 游戏,我需要在地图上创建多边形领土,玩家可以点击它来移动他的单位。
我是被迫在多边形检测算法中使用某种点,还是有使用我已经绘制的多边形的更简单的解决方案?
到目前为止,我设法绘制了一个多边形,例如:
ALLEGRO_VERTEX v[] =
{
{ .x = 0, .y = 0, .z = 0, .color = al_map_rgb_f(1, 0, 0) },
{ .x = 0, .y = 48, .z = 0, .color = al_map_rgb_f(1, 0, 0) },
{ .x = 32, .y = 64, .z = 0, .color = al_map_rgb_f(1, 0, 0) },
{ .x = 80, .y = 32, .z = 0, .color = al_map_rgb_f(1, 0, 0) },
{ .x = 112, .y = 0, .z = 0, .color = al_map_rgb_f(1, 0, 0) }
};
al_draw_prim(v, NULL, NULL, 0, 5, ALLEGRO_PRIM_TRIANGLE_FAN);
编辑:好的,我想我可以使用 this algorithm 检测鼠标是否在多边形中,但我仍然觉得这不是正确的方法。我仍然需要为每个不同的多边形调用该函数,这听起来不对。
您找到了一种算法,可以对所有多边形执行 point-in-polygon 并告诉您用户单击了哪个多边形。干得好,你可以使用它。你想要一个 built-in API 调用来完成它但没有得到它。由于没有其他人发布相反的答案,我想你不会。你应该使用你所拥有的。
我现在将说明为什么这应该感觉正确而不是感觉不正确。
如果库本身已经为您实现了它,它仍然会受到底层 OS 原语的约束,而这些原语又会受到问题算法复杂性的约束,每个多边形 point-in-polygon。因此,您可以在您的应用程序中投影所有多边形,对整个屏幕使用一个鼠标点击框,然后依次测试它们。如果有 API 的话,这就是 API 必须做的事情。
我预计您编写代码后发现速度太慢的可能性很大。一个几乎总是有效的简单解决方案是先进行 axis-oriented 边界框测试,这很快。
BugSquasher 建议替代解决方案。渲染两次,第二次渲染到屏幕外缓冲区,每个多边形使用一种颜色,point-test 颜色。这也有效,如果 hit-testing 比多边形移动更常见,这是一个很好的加速。不过它确实会消耗内存。
我正在使用 allegro 库创建一个 2D 游戏,我需要在地图上创建多边形领土,玩家可以点击它来移动他的单位。
我是被迫在多边形检测算法中使用某种点,还是有使用我已经绘制的多边形的更简单的解决方案?
到目前为止,我设法绘制了一个多边形,例如:
ALLEGRO_VERTEX v[] =
{
{ .x = 0, .y = 0, .z = 0, .color = al_map_rgb_f(1, 0, 0) },
{ .x = 0, .y = 48, .z = 0, .color = al_map_rgb_f(1, 0, 0) },
{ .x = 32, .y = 64, .z = 0, .color = al_map_rgb_f(1, 0, 0) },
{ .x = 80, .y = 32, .z = 0, .color = al_map_rgb_f(1, 0, 0) },
{ .x = 112, .y = 0, .z = 0, .color = al_map_rgb_f(1, 0, 0) }
};
al_draw_prim(v, NULL, NULL, 0, 5, ALLEGRO_PRIM_TRIANGLE_FAN);
编辑:好的,我想我可以使用 this algorithm 检测鼠标是否在多边形中,但我仍然觉得这不是正确的方法。我仍然需要为每个不同的多边形调用该函数,这听起来不对。
您找到了一种算法,可以对所有多边形执行 point-in-polygon 并告诉您用户单击了哪个多边形。干得好,你可以使用它。你想要一个 built-in API 调用来完成它但没有得到它。由于没有其他人发布相反的答案,我想你不会。你应该使用你所拥有的。
我现在将说明为什么这应该感觉正确而不是感觉不正确。
如果库本身已经为您实现了它,它仍然会受到底层 OS 原语的约束,而这些原语又会受到问题算法复杂性的约束,每个多边形 point-in-polygon。因此,您可以在您的应用程序中投影所有多边形,对整个屏幕使用一个鼠标点击框,然后依次测试它们。如果有 API 的话,这就是 API 必须做的事情。
我预计您编写代码后发现速度太慢的可能性很大。一个几乎总是有效的简单解决方案是先进行 axis-oriented 边界框测试,这很快。
BugSquasher 建议替代解决方案。渲染两次,第二次渲染到屏幕外缓冲区,每个多边形使用一种颜色,point-test 颜色。这也有效,如果 hit-testing 比多边形移动更常见,这是一个很好的加速。不过它确实会消耗内存。