2011-07-21 11 views
1

オンラインのJavaゲームコードがいくつか見つかりました。私はそれを修正しようとしています。私はJFrameから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

短い答え:は、あなたのBoard.paint()方法でsuper.paint()を呼び出すことはありません。

長時間の回答:アプレットはコンストラクタの一部としてsetBackground(Color.WHITE);で設定した背景色を含む独自の表示プロパティを持つコンテナです。 super.paint(g)を呼び出すことにより、アプレットは白い背景を表示グラフィックスにペイントするだけでなく、含まれているコンポーネントペインティングを呼び出すようになります。これがちらつきの原因です - それぞれのペイントサイクルでは、画面上の表示を白で塗りつぶしてから、offscreenBufferイメージをオンスクリーンディスプレイにコピーしています。

おそらく明示的に、アプレットの背景を忘れて、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

ゲームエンジンを見てみましょうBonsaiIvo Wetzelから。それは大好きです。

BufferStrategyを使用していますが、これはダブルバッファーに最適な方法だと思います。

関連する問題