10

我正在使用用于绘图的 Java2D 库在 Java 中创建一个 2D 游戏,我真的需要一个浮点精度的 Polygon 对象,我可以使用它来绘制游戏对象并对其进行碰撞检测。不幸的是,Java 的 Polygon 对象仅具有 int 精度,并且没有像 Rectangle 和 Rectangle2D 那样等效的 Polygon2D。我已经做了足够多的研究,发现我有一些选择,但它们似乎都不是很好。

  1. 使用 Path2D。根据该论坛中的一位 Java 开发人员的说法,Polygon2D 的缺失是一个疏忽,但建议将其替换为 Path2D。不幸的是,Path2D 没有提供访问其各个顶点或边的方法,这是我进行碰撞检测所需要的(特别是我需要获得与每条边正交的向量)。

  2. 实现我自己的实现 Shape 接口的 Polygon2D,以便我仍然可以将它传递给Graphics2D.draw(Shape). 这看起来会非常困难。Shape 接口需要一些难以实现的方法,例如contains(Rectangle2D)getPathIterator(AffineTransform)。特别是,为了getPathIterator实现它,我似乎需要返回一个 PathIterator 类型的对象,但是公共 AWT 包中没有可用的 PathIterator 接口的具体实现。

  3. 将 Path2D 包装在一个“记住”各个顶点并将它们提供给客户端的对象中。当我需要一个记住其组件形状的 Area 时,这对我有用:我将它包装在一个 CompoundShape 类中,该类实现了 Shape 接口并将所有 Shape 方法转发给 Area 的实现,同时跟踪添加到ArrayList 中的区域。这样做的问题是,如果我跟踪两个floats 数组中的各个顶点,则无法在用户更改顶点的情况下将它们公开给用户 - 因为这将通过直接数组访问发生,内部 Path2D 不会收到更改通知。

  4. 复制 Polygon.java。Java 的 Polygon 类的实际源代码可在 grepcode.com 上获得,我可以简单地将与顶点相关int的 s替换为floats 以获得 Polygon2D。不幸的是,当我尝试这样做时,该行import sun.awt.geom.Crossings;引发了一个编译器错误,提示“由于所需库 C:\Program Files\Java\jre7\lib\rt.jar 的限制,无法访问类型交叉点。” 根据这个问题,因为 Sun 的许可协议阻止您用自己的 Java 类替换核心 Java 类,但 Polygon 并没有尝试这样做——它只是创建了一个 sun.awt.geom.Crossings 类型的对象,没有替换或扩展发生了,我确保将我的 Polygon 副本放在一个不称为“java”的包中。

进行此操作的最佳方法是什么?我会很感激关于如何使这些选项中的一个起作用的建议,或者关于另一个没有遇到这些问题的选项的想法。

4

3 回答 3

7

我也会推荐Path2DGeneralPath是一个遗留类;不要使用它。

Path2D 确实提供了对顶点值的访问,尽管它是一种迂回的方式。您需要使用PathIterator

PathIterator pi = path.getPathIterator(null);
float[] value = new float[6];
float x = 0, y = 0;

while (!pi.isDone()) {
    int type = pi.currentSegment(values);
    if (type == PathIterator.SEG_LINETO) {
        x = values[0];
        y = values[1];
    }
    else if (type == PathIterator.SEG_CLOSE) {
        x = 0;
        y = 0;
    }
    else {
        // SEG_MOVETO, SEG_QUADTO, SEG_CUBICTO
    }
    pi.next();
}

当您准备好花哨时,您可以扩展它支持二次曲线和三次曲线。我假设您现在不需要那些,因为您正在谈论多边形。

此外,Path2D 有一些方便的静态方法来测试路径是否与矩形相交以及路径是否包含矩形或点。可悲的是,没有任何方法可以测试与另一条路径相交或包含另一条路径的路径。

于 2012-08-21T21:21:55.467 回答
1

也许多边形的内部具有不同的比例?

写入时乘以大数并类型转换为int,读取时除以相同的大数?

于 2013-01-12T06:42:21.860 回答
0

你可以使用第 3 方库吗?如果是这样,我是否建议使用Slick 2D Polygon类。我要做的是在内部,为您的实际多边形使用这个类来检查与包含的交集,然后当您需要绘制时,只需将float值转换为int并绘制 Java2D 多边形。

我知道这可能不是最佳解决方案,但它可能适用于您正在做的事情。

于 2012-08-21T21:29:17.923 回答