2012-05-08 38 views
5

所以在我正在做的游戏中,我有一个大理石跟着鼠标,但是当它做到这一点时,屏幕闪烁。如何在java中为游戏增加两倍缓冲区?

背景包括两个jpegs和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) 
    { 

    } 
} 

回答

16

双缓冲概念相当简单,而不是逐个绘制你的对象,在绘制的图像上,然后告诉渲染器来绘制整个图像。这消除了闪烁。

这里有一个如何做到这一点(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); 
    } 
} 

Nowdays一个例子,你不必自己实现,你可以使用BufferStrategy使用和相关型号的类。看到lakam99的答案就是一个例子。

+0

非常感谢:) –

+0

很好的答案,但你并不需要这样做的摇摆已经提供了双缓冲。看到我的答案的细节.... – mikera

+0

@dfb'油漆(offgc)后';'图像离线界面如何更新?我没有看到屏幕上的变量在任何地方变化。 –

1

我认为你的问题不是双缓冲。您必须在绘画方法的第一行添加super.paint(page);

2

Swing支持自动双缓冲,所以你不需要编码任何东西。

只需拨打顶级组件(通常是一个JPanel)setDoubleBuffered(true),它应该所有的工作。

参见:setDoubleBuffered

2

另一种解决方案是使用,会为你增加一倍缓冲库。既然你使用的是Java2D,我假设你想保持一切都非常轻量级和低级别。我认为Slick2D在提供简单的2d绘图和输入功能方面做得非常出色,不会妨碍您的发展。它感觉像是一个更优雅的Java2D版本,但是写​​在了OpenGL上。一旦你用纯Java创建了几个应用程序,我认为转向Slick2D是一个伟大的想法。这不是对你的问题的直接解决方案,但是因为它已经被解决了,所以我认为Id提供了一些建议,这将使你的Java游戏开发生活变得更容易。检查出来,如果你有机会http://slick.cokeandcode.com/