你好我正在写一个小游戏,它已经快完成了,唯一不起作用的是ImageBuffer。我每10毫秒调用一次方法repaint()。我的paint()方法如下:
private Graphics2D g2D;
public void paint (Graphics g) {
BufferedImage bimage = ((Graphics2D)g).getDeviceConfiguration().createCompatibleImage(700, 600, Transparency.OPAQUE);
g2D = bimage.createGraphics();
g2D.setFont(font);
for(Wall wall: walls){
wall.paint(g2D);
}
g2D.setColor(Color.orange);
paddle.paint(g2D);
g2D.drawString(score + "", 150,50);
g2D.drawString("record: "+topscore , 350,50);
g2D.setColor(Color.red);
ball.paint(g2D);
g.drawImage(bimage,0,0,this);
}
但这似乎并没有消除闪烁。我认为在bufferedimage开始绘制之前屏幕会被清除。 任何人都可以帮我解决这个问题吗? 谢谢!
答案 0 :(得分:2)
您需要覆盖update
:
public void update() {
paint();
}
update
的默认实现在调用paint
之前用背景颜色填充整个区域,这就是导致闪烁的原因。
答案 1 :(得分:1)
您应该扩展JComponent
而不是Canvas
,具体取决于您使用的是Swing而不是AWT。这样做可以为您提供一个很好的轻量级组件,并且不需要您实现双缓冲支持。然后,在被覆盖的paintComponent(..)
中使用提供的Graphics对象绘制图像。
关于原始代码的主题,在绘画中每次创建一个新的兼容图像都是可怕的(这是一个使用大字节缓冲区的非常昂贵的操作 - 你会经常出现GC暂停)。如果你真的想要在AWT中进行双缓冲(这会在调整大小时让你闪烁,但在小程序中应该没问题),你应该调查BufferStrategy。
编辑:将组件更改为JComponent,oops:)
答案 2 :(得分:1)
我无法从发布的代码中确切地说出你在做什么,但我猜你正试图在顶部绘制一些带有一些动态图像的背景图像。如果是这样,那么你的做法是错误的。
每次调用绘画时,您都不希望重新创建背景图像。相反,缓冲图像应该在paintComponent()方法之外创建一次。然后,当您重新绘制组件时,首先只绘制图像(作为背景)。然后在背景上绘制球拍和球。
另一种方法是使用JLabel来表示你的球拍和球。然后移动组件,只需更改其位置即可。然后,只需要重新绘制组件的旧/新位置,而不是整个背景,这也更有效。