2013-07-22 54 views
3

不應該三重緩衝,Canvas是被動渲染的最佳解決方案嗎?我剛剛寫了這個顯示一個圓的java代碼。如果我將buffersraterate設置爲3,它會閃爍很多。如果我把它降低到2或1就沒關係。也許我做錯了什麼?三重緩衝重閃爍

public void run(){ 

    while (running){ 
     update(); 
     draw(); 
    } 
} 


public void update(){ 

} 


public void draw(){ 
     BufferStrategy bs = getBufferStrategy(); 
     if (bs==null){ 
     createBufferStrategy(3); 
     return; 
     } 

     Graphics g = bs.getDrawGraphics(); 
     g.setColor(Color.BLACK); 
     g.fillOval(30, 30, 20, 20); 
     g.dispose(); 
     bs.show(); 
} 

,這是JFrame類,我把畫布

public class Game { 

public static void main (String [] args){ 

    Pan game = new Pan(); 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setResizable(true); 
    frame.add(game); 
    frame.pack(); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
    game.start(); 

} 

} 
+2

一點點,我會小心混合重和輕重量的部件 – MadProgrammer

回答

3

有兩件事情在我身上跳出來。

  1. 「循環」運行沒有任何延遲。這意味着屏幕會盡可能多次更新,這對於硬件來說可能非常重要。一般來說,你想瞄準大約25fps,這有助於提供平穩運動的幻覺
  2. 你沒有準備Graphics繪畫。每當您從BufferStrategy獲得Graphics上下文時,您實際上都會獲得最後一次使用的上下文。這意味着,所畫的一切仍然存在。你需要清理這個。閃爍(可能)來自這樣一個事實,即其中一個Graphics上下文已經被填充顏色,而其他的沒有。

下面是一個非常簡單的例子,包括動畫

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.image.BufferStrategy; 
import javax.swing.JFrame; 

public class DoubleBuffer { 

    public static void main(String[] args) { 

     Pan game = new Pan(); 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(true); 
     frame.add(game); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
     game.start(); 

    } 

    public static class Pan extends Canvas implements Runnable { 

     private int xDelta = 2; 
     private int x = 0; 
     private int y = 20; 

     public Pan() { 
     } 

     public void start() { 
      new Thread(this).start(); 
     } 

     public void run() { 

      while (true) { 
       update(); 
       try { 
        Thread.sleep(40); 
       } catch (InterruptedException ex) { 
       } 
       draw(); 
      } 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     public void update() { 
      x += xDelta; 
      if (x + 20 > getWidth()) { 
       x = getWidth() - 20; 
       xDelta *= -1; 
      } else if (x < 0) { 
       x = 0; 
       xDelta *= -1; 
      } 
     } 

     public void draw() { 
      BufferStrategy bs = getBufferStrategy(); 
      if (bs == null) { 
       createBufferStrategy(3); 
       return; 
      } 

      Graphics g = bs.getDrawGraphics(); 
      g.setColor(Color.RED); 
      g.fillRect(0, 0, getWidth(), getHeight()); 
      g.setColor(Color.BLACK); 
      g.fillOval(x, y, 20, 20); 
      g.dispose(); 
      bs.show(); 
     } 
    } 
} 
1

試試這個:

做一個BufferedImagemyPanel類是這樣的:

private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

現在將該圖像繪製在上面一切在你的繪製方法是這樣的:

public void draw(){ 
    BufferStrategy bs = getBufferStrategy(); 
    if (bs== null){ 
     createBufferStrategy(3); 
     return; 
    } 

    Graphics g = bs.getDrawGraphics(); 
    g.drawImage(image, 0, 0, getWidth(), getHeight(), null); 
    // Draw your other stuff after this... 
    g.fillOval(20, 20, 20, 20); 
    g.dispose(); 
    bs.show(); 
} 

這將在屏幕上繪製黑色背景,以便它不再閃爍。現在你可以在該圖像上繪製任何東西。

+0

完美的答案。謝謝。 – Muteking

+0

沒問題!確保接受它,當你可以請;;) –