Pregunta

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.

¿Fue útil?

Solución

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).

  1. 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.

  2. 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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top