我正在做一些java游戏,我想如果游戏是在不导入图像的情况下制作的,那就太酷了。因此,我需要创建自定义形状并将其交给 Graphics 对象进行绘制。我的游戏中的主要角色将是一个团子,它很像史莱姆,由一个不完美的圆圈和两条垂直线作为眼睛组成。我应该能够通过给定指示大小的参数来构造团子。另外,如果我可以修改眼睛的位置,或者底部曲线来呈现与地板的交互,那就更好了。此外,如果我可以用颜色填充它并赋予它一些纹理或其他东西,我会很高兴。但一切事物都是从一个圆和两条线开始的。
我检查了一些API,包括、、、、、和Shape一些源代码。我学会了如何使用GeneralPath绘制直线、二次曲线和贝塞尔曲线。但我仍然不知道如何实现我的自定义形状。我在 stackoverflow 中发现了这个问题,但没有发布好的答案。GeneralPathPathIteratorAreaEllipse
如果有人只看了标题而跳过了这个问题的内容,我要强调这个问题是关于创建自定义形状,这意味着实现“Shape”接口。不仅仅是画一个形状。
于是经过一天的研究,我终于做到了。对于任何和我有同样问题的人,我建议你做我所做的事情。
首先参考java api源码,这里我选择了Ellipse2D.class的源码。看了源码,你可能会忽略2个内部静态类Ellipse2D.Double,Ellipse2D.Float它们此时并不那么重要。
要实现该Shape接口,最重要的方法是
public PathIterator getPathIterator(AffineTransform at) {
return new EllipseIterator(this, at);
}
Run Code Online (Sandbox Code Playgroud)
该方法由paintComponent调用以获取PathIterator要绘制的内容。因此,正如源代码的作用一样,您可以创建自己的ShapeIterator.
然后是EllipseIterator的源代码。如您所见,有 4 个方法(不包括构造函数和重复项)。您可以离开getWindingRule()进行进一步的研究。而isDone()和 则next()相当容易理解。
那么我们就重点来说一下public int currentSegment(float[] args)。
返回值是 int,应该是静态最终 int 字段:SEG_CLOSE、SEG_CUBICTO等。它们给出了绘制形状的说明。SEG_MOVE将移动起点,SEG_LINETO将从起点到终点绘制一条直线。还有一些像二次曲线和贝塞尔曲线这样的,你可以在java api上查看详细信息。
参数float[] args也应该被视为返回值语句。它提供上述指令的参数。对于SEG_MOVETO, SEG_LINETO,您需要 2 个参数,因此修改 args[0] 和 args[1] (x 和 y)。对于SEG_QUADTO,您需要 4 个参数,并且SEG_CUBICTO需要 6 个。
仔细遵循源代码,创建形状并不难。我还没有完成 Shape 接口中的所有方法,但是形状已经可以由 g2d 实例绘制。
| 归档时间: |
|
| 查看次数: |
3799 次 |
| 最近记录: |