所以在我正在制作的游戏中,我有一个大理石跟随鼠标,但当它这样做时屏幕闪烁。
背景包括两个jpeg和9个矩形。我该如何进行双缓冲呢?这是主窗口的代码。
/**
* Write a description of class Window here.
*
* @author (your name)
* @version (a version number or a date)
*/
public class Window extends JApplet implements MouseMotionListener
{
private BufferedImage image;
private BufferedImage side;
private int mouseX;
private int mouseY;
public Window(){
try {
image = ImageIO.read(new File("Backgrounds/violet.jpg"));
side = ImageIO.read(new File("Backgrounds/side margin.jpg"));
} catch (IOException ex) { }
}
private void delay(int delay)
{
try {
Thread.sleep(delay);
} catch (InterruptedException e) {}
}
public void init()
{
this.addMouseMotionListener(this);
}
public void paint (Graphics page)
{
page.drawImage(image, 0, 0, null);
page.setColor(Color.blue);
page.fillRect(0, 0, 160, 160);
page.setColor(Color.black);
page.fillRect(15, 15, 130, 130);
page.setColor(Color.green);
page.fillRect(340, 0, 160, 160);
page.setColor(Color.black);
page.fillRect(355, 15, 130, 130);
page.setColor(Color.yellow);
page.fillRect(0, 340, 160, 160);
page.setColor(Color.black);
page.fillRect(15, 355, 130, 130);
page.setColor(Color.red);
page.fillRect(340, 340, 160, 160);
page.setColor(Color.black);
page.fillRect(355, 355, 130, 130);
page.drawImage(side, 500, 0, null);
page.drawString(Score.getScore(), 560, 110);
//conveyors
page.setColor(Color.gray);
page.fillRect(235, 0, 30, 160);
//marble
delay(100);
page.fillOval(mouseX, mouseY , 40, 40);
}
public void mouseMoved(MouseEvent e)
{
mouseX = e.getX();
mouseY = e.getY();
repaint();
}
public void mouseDragged(MouseEvent e)
{
}
}
答案 0 :(得分:17)
双缓冲在概念上非常简单,不是逐个绘制对象,而是在图像上绘制它们,然后告诉渲染器绘制整个图像。这消除了闪烁。
以下是您可以执行此操作的示例(source)
class DoubleBufferedCanvas extends Canvas {
public void update(Graphics g) {
Graphics offgc;
Image offscreen = null;
Dimension d = size();
// create the offscreen buffer and associated Graphics
offscreen = createImage(d.width, d.height);
offgc = offscreen.getGraphics();
// clear the exposed area
offgc.setColor(getBackground());
offgc.fillRect(0, 0, d.width, d.height);
offgc.setColor(getForeground());
// do normal redraw
paint(offgc);
// transfer offscreen to window
g.drawImage(offscreen, 0, 0, this);
}
}
现在,您不必自己实现,您可以使用BufferStrategy和相关的类。有关此示例,请参阅lakam99的答案。
答案 1 :(得分:4)
Swing支持自动双缓冲,因此您无需编写任何代码。
只需在您的顶级组件(通常是JPanel)上调用setDoubleBuffered(true)
,它就可以正常工作。
答案 2 :(得分:2)
另一个解决方案是使用一个为您提供双缓冲的库。由于您使用的是Java2D,我假设您希望保持一切非常轻巧和低级别。我认为Slick2D可以很好地提供简单的2D绘图和输入功能而不会妨碍你。它感觉像是一个更优雅的Java2D版本,但它是用OpenGL编写的。一旦你使用纯Java制作一些应用程序,我认为转向Slick2D是一个很好的想法。这不是您问题的直接解决方案,但由于它已经解决,我认为我提供了一些建议,可以让您的Java游戏开发更轻松。如果有机会http://slick.cokeandcode.com/
,请查看答案 3 :(得分:1)
我认为你的问题不是双重缓冲。您必须在绘制方法的第一行添加super.paint(page);
。