Rice_Crisp
Rice_Crisp

Reputation: 1261

Image rotation animation

Perhaps a question with a simple answer. I'm trying to animate a ship (asteroids style). Right now I'm just using the Graphics2D rotate method. However, right now it's just blurring my image. What's the simplest way of going about this and getting it to work correctly? (the getImage method gets called every time the screen refreshes, and the rotate method gets called every time the user presses left or right. bi1 is the bufferedimage read in previously)

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;
}

Upvotes: 3

Views: 3158

Answers (6)

Frank Visaggio
Frank Visaggio

Reputation: 3712

try it using an 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

Upvotes: 2

Nikson Kanti Paul
Nikson Kanti Paul

Reputation: 3440

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)

Upvotes: 0

user1149913
user1149913

Reputation: 4523

You are drawing to the graphics context of the BufferedImage that is storing your ship image.

Your use of the rotate method should work if you draw to the graphics context of the UI component that is displaying the game or the context of some other buffer.

Upvotes: 0

Gene
Gene

Reputation: 46960

I agree with the suggestion on Graphics2D.setRenderingHint(). Try KEY_INTERPOLATION with VALUE_INTERPOLATION_BILINEAR.

Additionally, try making the source image up to 4 times bigger than you actually want to draw it and then use Graphics2D.scale(1/multiple) in addition to the rotation.

The reason: Without scaling, the diagonal of a pixel is 1.4+ times as large as an edge, so as the rotation approaches the odd 45 degree multiples, 14+ pixels in the image are being drawn with reference to only 10 in the original image. This adds raggedness to the result.

Another approach is to use BufferedImage for both 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, switching to OpenGL (e.g. with JOGL or LWGL), provides all kinds of control over anti-aliasing and much more. On the other hand, it opens a door for hardware incompatibilities as many graphics drivers have OpenGL bugs IME.

Upvotes: 1

sagaofsilence
sagaofsilence

Reputation: 139

Have you given try to BufferedImage?

Upvotes: 0

Durandal
Durandal

Reputation: 20059

You can try playing with Graphics.setRenderingHint() and set a higher quality, but other than that there isn't anything you can do to make it work 'right'.

If the quality provided by Graphics2D does not satisfy your demands, create rotated images of your 'spaceship' with a graphics program and select the correct pre-rotated image depending on the facing of the ship. This way the quality depends no longer on the graphics API, but only on your graphics program (and how much effort you put into making the rotated images). You have to decide on a granularity (number of prerendered images) for the angle, sane numbers are usually between 16 to 64.

Upvotes: 2

Related Questions