我正在使用Java2D库在Java中创建2D游戏,我真的需要一个浮点精度的Polygon对象,我可以用它来绘制游戏对象并对它们进行碰撞检测.遗憾的是,Java的Polygon对象仅以int精度出现,并且没有像Rectangle和Rectangle2D那样的等效Polygon2D.我已经做了足够的研究,看到我有一些选择,但它们似乎都不是很好.
使用Path2D.根据Java开发人员在本论坛发帖称,缺少Polygon2D是一种疏忽,但其建议的替代品是Path2D.不幸的是,Path2D没有提供访问其各个顶点或边的方法,这是我进行碰撞检测所需要的(具体来说,我需要得到一个与每条边正交的矢量).
实现我自己的Polygon2D实现Shape接口,这样我仍然可以传递给它Graphics2D.draw(Shape).这看起来很难.Shape接口需要像contains(Rectangle2D)和那样的棘手实现方法getPathIterator(AffineTransform).对于getPathIterator特别,好像是为了实现它我需要返回类型的PathIterator的对象,但也有接口的PathIterator在公共AWT封装没有具体实现.
在一个"记住"各个顶点并将它们提供给客户端的对象中包裹Path2D.当我需要一个记住其组件形状的区域时,这对我有用:我将它包装在一个实现Shape接口的CompoundShape类中,并将所有Shape方法转发到Area的实现,同时跟踪添加到其中的每个Shape. ArrayList中的区域.这样做的问题是,如果我跟踪两个floats 数组中的各个顶点,就没有办法将它们暴露给用户而没有用户更改顶点的可能性 - 并且因为直接阵列访问会发生这种情况,内部Path2D不会收到有关更改的通知.
复制Polygon.java.Java的Polygon类的实际源代码可以在grepcode.com上找到,我可以简单地用ints 替换与顶点相关的floats来获得Polygon2D.不幸的是,当我尝试这个时,该行import sun.awt.geom.Crossings;抛出一个编译器错误,说"由于对所需库C:\ Program Files\Java\jre7\lib\rt.jar的限制,无法访问类型交叉".根据这个问题,因为Sun的许可协议阻止您用自己的替换核心Java类,但Polygon不会尝试这样做 - 它只是创建了一个类型为sun.awt.geom.Crossings的对象,没有替换或扩展发生了,我确保将我的Polygon副本放在一个名为"java"的包中.
进行此操作的最佳方法是什么?我很欣赏这些选项中的一个如何工作的建议,或者对于没有遇到这些问题的另一个选项的想法.
我也推荐Path2D.GeneralPath是一个遗留类; 不要使用它.
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();
}
Run Code Online (Sandbox Code Playgroud)
当你准备好了,你可以扩展其他,以支持二次曲线和三次曲线.我假设你在谈论多边形的时候并不需要那些.
此外,Path2D有一些方便的静态方法,用于测试路径是否与矩形相交以及路径是否包含矩形或点.遗憾的是,没有方法可以测试相交或包含其他路径的路径.