2017-01-08 5 views
0

この質問は「全画面が点滅していません」という質問のタイプです。再描画時に特定のオブジェクトがちらつく

私は画面全体をJavaグラフィックスを理解しようとすると、簡単なゲームを作ったが、シーンは、新しいオブジェクトと再描画されると、いくつかのオブジェクトがちらつく続け、odlyておりません。おそらく、この問題が発生する可能性がありますどのような

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

private void render() { 
     BufferStrategy bs = this.getBufferStrategy(); 
     if(bs == null){ 
      createBufferStrategy(6); 
      return; 
     } 
     Graphics g = bs.getDrawGraphics(); 
     Graphics2D g2d = (Graphics2D)g; 
     //fill screen with black background 
     g.drawImage(image, 0, 0, getWidth(), getHeight(), null); 
     //draw cool stuff 
     try { 
      for (int i = 0; i < Element.elements.size(); i++) { 
       Element.elements.get(i).render(g2d); 
      } 
     } catch (Exception e) { 
      System.err.println("No such element to render"); 
     } 
     //dispose graphics 
     g.dispose(); 
     g2d.dispose(); 
     bs.show(); 
} 

:ここ

は私render()方法ですか?私は気泡の量がこの問題を引き起こすとは思わない。

あなたがチェックアウトしたい場合は、このプロジェクトのzip fileで、 これはマウス移動のイベントスレッドで行われているの.jar file

+0

コードに間違いはありません。通常、awt/swingアプリケーションで画面がちらつくときは、SwingUtilities.InvokeLater()を使用していたものがあるため、このペイント中にページの一部だけが再描画され、後で他の部分が再描画されるためです。次に、キャンバスがダブルバッファされていることを確認した後、私はアイデアがありません。 –

答えて

2

お使いのモデルの更新は、同期させる必要がありますあなたのレンダリングスレッドで。レンダリングが発生すると、モデルが矛盾した状態になることがあるため、フリッカーが発生します。この問題を解決するために

一つの方法は、あなたがあなたのモデルを更新しているスレッドでレンダリングすることですあなたはSwingUtilitiesとイベントスレッドでレンダリングを実行することができます。

try { 
    SwingUtilities.invokeAndWait(new Runnable() { 
     @Override 
     public void run() { 
      render(); 
     } 
    }); 
} catch (InvocationTargetException | InterruptedException e) { 
    running = false; 
    System.err.println("Render interrupted"); 
} 

あなたはそのコンポーネントを使用している場合AWTまたはSwingによってレンダリングされます。常にイベントスレッドでレンダリングを行います。

レンダリングプロセス全体を自分で制御するので、別のスレッドでレンダリングするオプションがありますが、モデルへのアクセスを同期させる必要があります(つまり、イベントスレッドによって実行されるモデルへの書き込みは、レンダリングスレッドによって実行された読み込みと同期されます)。例えば

:(イベントスレッドから呼び出される)Shredder.scan()

public static void scan() { 
    synchronized (Element.elements) { 
     for (Element element : Element.elements) { 
      if (element.containsMouse()) { 
       if (element.getSize() < 24) { 
        Element.elements.remove(element); 
       } else { 
        element.cloneItself(); 
        Element.elements.remove(element); 
       } 
       skip = true; 
       break; 
      } 
     } 
    } 
} 

そして、あなたのレンダリングスレッドで:

synchronized (Element.elements) { 
    for (int i = 0; i < Element.elements.size(); i++) { 
     Element.elements.get(i).render(g2d); 
    } 
} 

形式の問題として、それは良いでしょう呼び出し元のコードが一貫性​​を維持することに関わる必要がないように、同期させる必要のあるコードを単一の場所に配置するアイデア。

+1

これはコンポーネントをペイントする場合に当てはまりますが、BufferStrategyを使用する場合は常に真であるとは限りません。 – VGR

+0

@VGR:これを明確にするために答えを更新しました。 – teppic

+0

さて、それを見てください。それは問題を解決しました。 – orkun

関連する問題