2012-05-08 42 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/