Image rotation animation

Perhaps a question with a simple answer. I am trying to animate a ship (asteroid style). Right now I'm just using the Graphics2D rotation method. However, now it just blurs my image. What's the easiest way to do this and make it work correctly? (the getImage method is called every time the screen is refreshed and the rotate method is called every time the user presses left or right. bi1 is a buffered read earlier)

public void rotate(double rot) {
    g = bi1.getGraphics();
    Graphics2D g2d=(Graphics2D)g;
    g2d.rotate(rot, 15, 15);
    g2d.drawImage(bi1, 0, 0, null);     
}

public BufferedImage getImage() {   
    return bi1;
}

      

+3


source to share


6 answers


try it with affine transformation:

  public void paint(Graphics g) {
      // clear off screen bitmap
      super.paint(g);
      // cast graphics to graphics 2D
      Graphics2D g2 = (Graphics2D) g;
      AffineTransform tfm = new AffineTransform();
      tfm.rotate(0,0,0);
      g2.setTransform(tfm);
      g2.drawImage(backImage, 0, 0, this);
      tfm.rotate(Math.toRadians(player.angle+90), player.x+32, player.y+32);
      g2.setTransform(tfm);
      g2.drawImage(tank, player.x, player.y, this);       
  }

      



http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/geom/AffineTransform.html

+2


source


You can try playing with Graphics.setRenderingHint () and setting it to a higher quality, but beyond that there is nothing you can do to get it to work "correctly".



If the quality provided by Graphics2D does not suit your needs, create rotated images of your "spaceship" with the graphics program and select the correct pre-rotated image depending on the appearance of the ship. Thus, quality is no longer dependent on the graphics API, but only on your graphics program (and how much effort you put into creating rotated images). You must decide on the detail (number of previews) for the angle, normal values ​​are usually between 16 and 64.

+2


source


I agree with the proposal by Graphics2D.setRenderingHint()

. Try KEY_INTERPOLATION

with VALUE_INTERPOLATION_BILINEAR

.

Also, try making the original image 4 times larger than you actually want to draw it, and then use it Graphics2D.scale(1/multiple)

in addition to the rotation.

Reason: Without scaling, the pixel diagonal is 1.4 times the edge, as the rotation approaches odd multiples of 45 degrees, 14+ pixels in the image are drawn with reference to only 10 in the original image. This adds zeal to the result.

Another approach is to use BufferedImage

for source and destination:

    tx = new AffineTransform();
    tx.rotate(theta, xCenter, yCenter)
    op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
    BufferedImage destImg = op.filter(srcImg, null);

      

Finally, going to OpenGL

(like using JOGL or LWGL) provides all kinds of control over anti-aliasing and more. On the other hand, it opens the door for hardware incompatibilities as many graphics drivers have OpenGL

IME errors.

+1


source


Have you asked for BufferedImage ?

0


source


You are drawing a graphics context BufferedImage that stores your ship image.

Your use of the rotate method should work if you are drawing the graphical context of a UI component that renders a game or some other buffer context.

0


source


you can use getRotateInstance(double theta)

public void paint(Graphics g) {
    ...
    Graphics2D g2d = (Graphics2D)bi1.getGraphics();
    AffineTransform af = new AffineTransform(
       AffineTransform.getRotateInstance(theta, x, y));
    g2d.setTransform(af);
    g2d.drawImage(bi1, af, this);
}

      

docs: AffineTransform (getRotateInstance)

0


source







All Articles