Reputation: 1596
I am doing some java games, and I figure it would be cool if the game is made without importing images. Therefore I need to create custom shapes and hand it to Graphics object to draw. The major character in my game will be a dango which is much like a slime, composing from a imperfect circle and two vertical lines as eyes. I should be able to construct dango by given a parameter indicating size. Also, it will be better if I can modify the position of the eyes, or the bottom curve to present the interaction with the floor. Further more, I would be glad if I can fill it with color and give it some texture or something. But all things start from a circle and two lines.
I checked some APIs including Shape
, GeneralPath
, PathIterator
, Area
, Ellipse
, and some source code. I learnt how to use GeneralPath to draw straight line, quadratic curve, and bezier curve. But still I don't know how to implement my custom shape. I found this question in stackoverflow but no good answer is posted.
In case someone just read the title and skips the content of this question, I shall emphasize that this question is about create the custom shape, which means to implement the 'Shape' interface. Not just to draw a shape.
Upvotes: 0
Views: 3862
Reputation: 1596
So after a day of research, I finally did it. For anyone who holds the same problem with me, I recommend you to do what I have done.
First, refer to the java api source code, here I chose the source code of Ellipse2D.class. Following the source code, you may ignore the 2 inner static class Ellipse2D.Double
, Ellipse2D.Float
, they are not so important at this point.
To implement the Shape
interface, the most important method is
public PathIterator getPathIterator(AffineTransform at) {
return new EllipseIterator(this, at);
}
this method is called by paintComponent to get a PathIterator
to draw. So as what the source code does, you may create your own ShapeIterator
.
Then the source code of EllipseIterator. As you can see, there are 4 methods (excluding the constructor and the duplicate). You may leave getWindingRule()
for furthur research. While isDone()
and next()
are rather simple to understand.
Then let's focus on public int currentSegment(float[] args)
.
The return values is int, which should be the static final int fields: SEG_CLOSE
, SEG_CUBICTO
, etc.. They give instructions on drawing your shape. SEG_MOVE
will move the start point, SEG_LINETO
will draw a straight line from start point to end point. There are few more like the quatratic curve and Bezier curve, you may check the details at java api.
The argument float[] args
should also be regarded as return value statement. It delivers the parameters for the instructions above. For SEG_MOVETO
, SEG_LINETO
, you need 2 params, so modify args[0] and args[1] ( x and y). For SEG_QUADTO
, you need 4 params, and SEG_CUBICTO
needs 6.
Carefully follows the source code, it won't be hard to create a shape. I haven't complete all the methods in Shape interface yet, but the shape can already be drawn by a g2d instance.
Upvotes: 5