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;
}
source to share
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
source to share
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.
source to share
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.
source to share