2015-08-08 82 views
2

我正在進入Java圖形,我正在閱讀Andrew Davison用Java編寫的Killer遊戲編程。他編寫了一個簡單的窗口應用程序,該應用程序使用Image類進行離屏渲染,然後將圖像複製到組件。我感到迷惑的是,一個可以只創建圖像,然後獲得與圖形上下文:用於屏幕外渲染的Java圖形(2D)

dbg = dbImage.getGraphics(); 

我覺得很困惑,因爲那時我們只使用DBG Graphics對象繪製的東西,但後來我們使用數據庫圖像中的paintComponent方法來顯示所有我們已經吸引到DBG對象的東西:

​​3210

那麼如何數據庫圖像「知道」,它包含了所有我們已經繪製到DBG Graphics對象的圖形的東西?

這裏是整個代碼:

public class GamePanel extends JPanel implements Runnable{ 

    private static final int PWIDTH = 500; 
    private static final int PHEIGHT = 400; 

    private Thread animator; 

    private volatile boolean running = false; 

    private volatile boolean gameOver = false; 

    private Graphics dbg; 
    private Image dbImage = null; 

    private Counter counter; 

    public GamePanel(){ 
     setBackground(Color.white); 
     setPreferredSize(new Dimension(PWIDTH, PHEIGHT)); 

     // create game components eg. counter. 
     counter = new Counter(10); 
     counter.start(); 
    } 

    private void stopGame(){ 
     running = false; 
    } 

    @Override public void addNotify(){ 
     super.addNotify(); 
     startGame(); 
    } 

    public void startGame(){ 
     if(animator == null || !running){ 
      animator = new Thread(this); 
      animator.start(); 
     } 
    } 

    @Override 
    public void run() { 
     running = true; 
     while(running){ 
      gameUpdate(); 
      gameRender(); 
      repaint(); 
      try{ 
       Thread.sleep(20); 
      } 
      catch(InterruptedException ex){ 
       // do something with the exception... 
      } 
     } 
    } 

    private void gameUpdate(){ 
     if(!gameOver){ 
      // update game state... 
      if(counter.getCounter() == 0) 
       gameOver = true; 

     } 
    } 

    private void gameRender(){ 
     if(dbImage == null){ 
      dbImage = createImage(PWIDTH, PHEIGHT); 
      if(dbImage == null){ 
       System.out.println("dbImage is null"); 
       return; 
      }  
      else 
       dbg = dbImage.getGraphics(); // get graphics context for drawing to off-screen images. 
     } 

     // clear the background 
     dbg.setColor(Color.white); 
     dbg.fillRect(0, 0, PWIDTH, PHEIGHT); 

     // draw game elements here... 
     dbg.setColor(Color.black); 
     dbg.drawString(Integer.toString(counter.getCounter()), 10, 10); 

     if(gameOver) 
      dbg.drawString("Game over...", 10, 20); 
    } 

    @Override public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     if(dbImage != null) 
      g.drawImage(dbImage, 0, 0, null); 
    } 
} 

的重要的部分是隻的paintComponent方法和gameRender()方法雖然。

+1

因爲'Graphics'實例是它自己的,所以它屬於圖像,沒有別的。簡單地說:'Image'實例保持對它的引用。 (或者相反,取決於實現,但最終結果是一樣的。) – biziclop

+0

所以createImage方法將dbg和dbImage綁定在一起@biziclop?它背後有一定的設計模式嗎? – kimsay

回答

5

基本上,Graphics對象不是你在上畫。這是你繪製

當您撥打dbImage.getGraphics()時,您的意思是「給我一個工具箱,讓我借鑑這張圖片」。 Graphics對象中的所有繪製方法都使用它創建的組件繪製。它們不在Graphics對象上繪製,它們繪製在屬於它的ImageComponent上。

認爲Graphics對象作爲調色板和畫筆,並在ImageComponent作爲畫布。

因此,當您完成dbg的運行後,這意味着您的圖像中充滿了彩色像素,此對象將其繪製在其上。現在,您可以拍攝該圖像並將其複製到另一個組件 - 通過在該組件的Graphics中使用drawImage「工具」 - 其「工具箱」。

+0

感謝您的明確回答@RealSkeptic。但是這在技術上如何工作? getGraphics方法是否以某種方式將Graphics和Image對象連接在一起? – kimsay

+2

@kismay當然是的。但具體的實現實際上取決於你所擁有的組件/圖像的類型,因爲像素的每個這樣的「光柵」都可以以不同的方式在內存中組織像素。所以實際上'getGraphics'爲你提供了一個專門爲你正在使用的圖像而構建的自定義對象。它恰好從'Graphics2D'繼承。 – RealSkeptic