2011-07-21 82 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,这是我认为加倍缓冲区的最好方法。

相关问题