2011-07-21 104 views
1

我在網上找到了一些Java遊戲代碼,我正在修改它。我將它從JFrame轉換爲Applet,但是每當我重新繪製屏幕時,我的遊戲就開始閃爍。我試過雙緩衝但沒有區別。爲什麼我的applet每次刷新都會閃爍?

來源:

private void paintDisks(Graphics g) { 
     try { 
      for (Disk d : disk) 
       paintDisk(g, d); 
     } catch (Exception ex) { 
      //System.out.println(ex.getMessage()); 
      paintDisks(g); // retry so the disks never not get painted 
     } 
    } 
    private void paintDisk(Graphics g, Disk d) { 
     if (d == null) 
      return; 
     if (diskimg[d.player] == null) { 
      g.setColor(colour[d.player]); 
      g.fillOval((int)d.x - 1, (int)d.y - 1, 32, 32); 
     } else { 
      g.drawImage(diskimg[d.player], 
         (int)d.x - 1, (int)d.y - 1, 
         32, 32, this); 
     } 
    } 

    @Override 
    public void paint(Graphics g) { 
     // paint real panel stuff 
     super.paint(g); 

     Graphics gr; 
     if (offScreenBuffer==null || 
       (! (offScreenBuffer.getWidth(this) == this.size().width 
       && offScreenBuffer.getHeight(this) == this.size().height))) 
     { 
      offScreenBuffer = this.createImage(size().width, size().height); 
     } 

     gr = offScreenBuffer.getGraphics(); 

     gr.clearRect(0,0,offScreenBuffer.getWidth(this),offScreenBuffer.getHeight(this)); 

     // paint the disks 
     paintDisks(gr); 

     // paint the curser ontop of the disks 
     paintCurser(gr); 

     g.drawImage(offScreenBuffer, 0, 0, this); 
    } 

    @Override 
    public void run() { 

     while (true) { 
      repaint(); 

      try { 
       Thread.sleep(9, 1); 
      } catch (InterruptedException ex) { 
       System.out.println(ex.getMessage()); 
      } 
     } 
    } 

} 
+1

如果您首先將其分解爲一個更簡單的自包含示例來說明問題,那麼您和我們可能會更容易進行調試。 – Ben

回答

3

簡短的回答:不叫super.paint()Board.paint()方法。

長答案:小程序也是一個容器,它有自己的顯示屬性,包括通過setBackground(Color.WHITE);作爲構造函數的一部分設置的背景顏色。通過調用super.paint(g),您正在使小程序將其白色背景繪製到顯示圖形上,並調用任何包含的組件繪畫。這是閃爍的原因 - 每個繪製週期,它將屏幕顯示畫爲白色,然後將您的offscreenBuffer圖像複製到屏幕顯示。

也許最好是明確的,忘掉Applet背景,刪除super.paint(g),然後自己完成所有的繪製步驟。您需要將clearRect()替換爲setColor()fillRect()。您也可以實施update()

@Override 
public void update(Graphics g) { paint(g); } 

@Override 
public void paint(Graphics g) { 
    // no super.paint(g) 

    if (offScreenBuffer==null || 
      (! (offScreenBuffer.getWidth(this) == this.size().width 
      && offScreenBuffer.getHeight(this) == this.size().height))) 
    { 
     offScreenBuffer = this.createImage(size().width, size().height); 
    } 

    Graphics gr = offScreenBuffer.getGraphics(); 

    // blank the canvas 
    gr.setColor(Color.WHITE); 
    gr.fillRect(0,0,offScreenBuffer.getWidth(this),offScreenBuffer.getHeight(this)); 

    // paint the disks 
    paintDisks(gr); 

    // paint the curser ontop of the disks 
    paintCurser(gr); 

    g.drawImage(offScreenBuffer, 0, 0, this); 
} 
1

看看從Ivo Wetzel遊戲引擎Bonsai。我很喜歡。

它使用BufferStrategy,這是我認爲加倍緩衝區的最好方法。

相關問題