也许是一个简单答案的问题。我正在尝试为船舶制作动画(小行星风格)。现在我只是使用Graphics2D旋转方法。然而,现在它只是模糊了我的形象。什么是最简单的方法来解决这个问题并让它正常工作? (每次屏幕刷新时都会调用getImage方法,每次用户按下左侧或右侧时都会调用rotate方法.bi1是先前读取的bufferedimage)
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;
}
答案 0 :(得分:2)
使用仿射变换尝试:
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
答案 1 :(得分:2)
您可以尝试使用Graphics.setRenderingHint()并设置更高的质量,但除此之外,您无法执行任何操作以使其正常工作。
如果Graphics2D提供的质量不能满足您的要求,请使用图形程序创建“宇宙飞船”的旋转图像,并根据船的表面选择正确的预旋图像。这样,质量不再取决于图形API,而只取决于您的图形程序(以及您为制作旋转图像所付出的努力)。你必须决定角度的粒度(预渲染图像的数量),理智的数字通常在16到64之间。
答案 2 :(得分:1)
我同意Graphics2D.setRenderingHint()
的建议。使用KEY_INTERPOLATION
尝试VALUE_INTERPOLATION_BILINEAR
。
此外,尝试使源图像最多比实际想要绘制的图像大4倍,然后在旋转之外使用Graphics2D.scale(1/multiple)
。
原因:没有缩放,像素的对角线是边缘的1.4倍,因此当旋转接近奇数45度的倍数时,图像中的14个像素仅参考10个像素原始图像。这增加了结果的粗糙。
另一种方法是对源和目标使用BufferedImage
:
tx = new AffineTransform();
tx.rotate(theta, xCenter, yCenter)
op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
BufferedImage destImg = op.filter(srcImg, null);
最后,切换到OpenGL
(例如使用JOGL或LWGL),提供对抗锯齿的各种控制等等。另一方面,它为硬件不兼容打开了一扇门,因为许多图形驱动程序都有OpenGL
错误IME。
答案 3 :(得分:0)
您是否试过BufferedImage?
答案 4 :(得分:0)
您正在绘制存储船舶图像的BufferedImage的图形上下文。
如果您绘制到显示游戏的UI组件的图形上下文或某些其他缓冲区的上下文,则您对rotate方法的使用应该有效。
答案 5 :(得分:0)
您可以使用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);
}