2012-11-27 66 views
7

我對java很陌生。我想製作一款遊戲。大量的研究後,我無法理解BufferStrategy中如何運作.. 我知道的基本知識..它創建以後可以把你的窗戶離屏圖像對象。我得到這個瞭解BufferStrategy

public class Marco extends JFrame { 
    private static final long serialVersionUID = 1L; 
    BufferStrategy bs; //create an strategy for multi-buffering. 

    public Marco() { 
     basicFunctions(); //just the clasics setSize,setVisible,etc 
     createBufferStrategy(2);//jframe extends windows so i can call this method 
     bs = this.getBufferStrategy();//returns the buffer strategy used by this component 
    } 

    @Override 
    public void paint(Graphics g){ 
     g.drawString("My game",20,40);//some string that I don't know why it does not show 
     //guess is 'couse g2 overwrittes all the frame.. 
     Graphics2D g2=null;//create a child object of Graphics 
     try{ 
     g2 = (Graphics2D) bs.getDrawGraphics();//this new object g2,will get the 
     //buffer of this jframe? 
     drawWhatEver(g2);//whatever I draw in this method will show in jframe, 
     //but why?? 
     }finally{ 
     g2.dispose();//clean memory,but how? it cleans the buffer after 
     //being copied to the jframe?? when did I copy to the jframe?? 
     } 
     bs.show();//I never put anything on bs, so, why do I need to show its content?? 
     //I think it's a reference to g2, but when did I do this reference?? 
    } 

    private void drawWhatEver(Graphics2D g2){ 
     g2.fillRect(20, 50, 20, 20);//now.. this I can show.. 
    } 
    } 

我不知道..我一直在研究這個很長一段時間..並沒有運氣..我不知道..也許它在那裏,它非常清晰和簡單,我「M太傻,看看吧..

感謝所有幫助.. :)

回答

18

下面是它如何工作的:

  1. 當您致電createBufferStrategy(2);時,JFrame構造了一個BufferStrategyBufferStrategy知道它屬於JFrame的特定實例。您正在檢索它並將其存儲在bs字段中。
  2. 當你需要繪製你的東西時,你需要從bs中檢索Graphics2D。這個Graphics2D對象綁定到bs所擁有的內部緩衝區之一。當你畫畫時,一切都進入了緩衝區。
  3. 當您最終致電bs.show()時,bs將導致您剛繪製的緩衝區成爲JFrame的當前緩衝區。它知道如何做到這一點,因爲(見點1)它知道它服務於什麼JFrame

就是這麼回事。

通過評論你的代碼...你應該改變你的繪圖程序了一下。取而代之的是:

try{ 
    g2 = (Graphics2D) bs.getDrawGraphics(); 
    drawWhatEver(g2); 
} finally { 
     g2.dispose(); 
} 
bs.show(); 

,你應該有一個這樣的循環:

do { 
    try{ 
     g2 = (Graphics2D) bs.getDrawGraphics(); 
     drawWhatEver(g2); 
    } finally { 
      g2.dispose(); 
    } 
    bs.show(); 
} while (bs.contentsLost()); 

這將有效地防止丟失緩衝框架,其中,根據the docs,會偶爾出現。

+0

爲什麼我們需要在show()之前處理()緩衝區?我假定圖形對象只有圖形功能,但是當不需要時,我們「釋放它的工具和資源」,並顯示我們的緩衝圖像? –

+1

@someFolk - 它不需要按順序完成;對'bs.show()'的調用可以在'try'塊內移動。但是沒有特別的理由要這樣做,並且一旦不需要它們就釋放系統資源是一種很好的做法。 –