私は非常に奇妙な問題に遭遇しました。何日も何日も答えを探してみました。私のゲームに新しいパーティクル システムが追加されましたが、遅すぎてプレイできませんでした。残念ながら、BufferedImage の変換は非常に低速です。爆発効果は、.png ファイルから読み込まれた約 200 個の白いスプライトで構成され、ランダムに回転、スケーリング、色付けされ、ランダムな速度で移動します。
トリプル/ダブルバッファリングでパフォーマンスを向上させようとしましたが、いくつかの問題に遭遇しました。
私の最初の試みは、ゲームが描かれた JPanel でした。JFrame のクラス (メイン) でバッファを設定し、ゲーム (JPanel を拡張) クラスで描画を行いましたが、Graphics g = bufferstrategy.getDrawGraphics(); は使用しませんでした。次に、描画メソッドの最後に、失われていないバッファー IF を示しました。Graphics オブジェクトを使用して描画を行っていないため、バッファーは常に「失われました」。しかし!ゲームは地獄のように速く実行されます!実用上バッファレス!しかし、どのように?
この試みは最終的にグラフィック エラーが発生せず、パフォーマンスが大幅に向上しましたが、nVidia / AMD カードのみでした。Intel GPU はこれを処理できませんでした。画面が白く点滅していました。
それで、BufferStrategyを正しく設定して使用することになりました。Game クラスは、JFrame から Graphics を取得するため、JPanel ではなく Canvas を拡張し、それを使用して JPanel で描画すると、タイトル バーの下に描画されるため、最終的にオフセットになります。それでも速い、60 FPSを修正。
さて、JFrame (メイン クラス) で BufferStrategy を作成したとき、まったく画像がありませんでした。Game クラス (Canvas) で BufferStrategy を設定することで、これを修正しました。写真は今では正しいですが、ゲーム自体はカタツムリのように遅いです. 1 回の爆発で FPS が最大 10 まで低下しますが、nVidia / AMD のみです。皮肉。古い Intel GPU でさえ 60 FPS で処理します。私は 5 ~ 6 年前の統合 Intel GPU で 60 FPS で 10000 個のパーティクルを動かすことができました。爆発が発生すると、カードの負荷が最大 100% になります。
これが私の主要なコードです(コード全体が不明確で長いです):
public class Game extends Canvas {
-snip-
public void tick() {
BufferStrategy bf = getBufferStrategy();
Graphics g = null;
try {
g = bf.getDrawGraphics();
paint(g);
} finally {
g.dispose();
}
if (!bf.contentsLost()) {
bf.show();
} else {
System.err.println("Buffer lost!");
}
Toolkit.getDefaultToolkit().sync();
}
public void setBuffers() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
if (gc.getBufferCapabilities().isMultiBufferAvailable()) {
createBufferStrategy(3);
System.out.println("Triple buffering active");
} else {
createBufferStrategy(2);
System.err.println("Triple buffering not supported by the GPU");
System.out.println("Double buffering active");
}
System.out.println("FullScreen required: " + getBufferStrategy().getCapabilities().isFullScreenRequired());
System.out.println("Page flipping: " + getBufferStrategy().getCapabilities().isPageFlipping());
}
public void paint(Graphics g) {
super.paint(g);
//set up RenderingHints, draw stuff
}
-snip snip-
}
もちろん、ゲームが開始されるとすぐに setBuffers() を呼び出します。
画像の操作は BufferedImage を使用して行う必要があるため、私の意見では VolatileImage を使用してもパフォーマンスが向上しないため、この問題は非常に重要です。些細なことを見逃しているか、間違った方法でやっているに違いありません。
ハードウェアの問題ではないことを示すために、私のコンピューターの仕様を次に示します。Intel Core i7-3770k @ 4.3GHz、nVidia GTX 460、12 GB RAM
「高速」コンピュータ: Intel Core 2 Duo @ 2.7 GHz、統合 Intel グラフィックス、2 GB RAM
あなたの助けと時間をありがとう!:)
編集 VolatileImage は役に立ちますか? 私が正しく知っていれば、BufferedImagesを使用して画像操作を行う必要がありますが、それらの描画は遅いです。