私は、画面上をスムーズにスクロールする必要のあるJavaアプリケーションを作成しています。私はこのアニメーションをできるだけスムーズにする方法を理解するために、さまざまなチュートリアルを経て年月をかけました。私が見る限り、ちらつきをなくすためにすべての通常の作業を行っています(オフスクリーンのバッファに描画し、1回でレンダリングし、更新を上書きして画面が空白にならないようにします)。しかし、アニメーションはまだちらつきます。各更新の前に空白になっているようです。Javaアニメーションのちらつきを解消する方法
私には基本的な(そしておそらくシンプルな)ものがあると確信していますが、私はアイデアがありません。問題を説明するクラスを投稿します。どんな助けでも大歓迎です。
import java.awt.*;
import javax.swing.*;
public class FlickerPanel extends JPanel implements Runnable {
private float [] pixelMap = new float[0];
/** Cached graphics objects so we can control our animation to reduce flicker **/
private Image screenBuffer;
private Graphics bufferGraphics;
public FlickerPanel() {
Thread t = new Thread(this);
t.start();
}
private float addNoise() {
return (float)((Math.random()*2)-1);
}
private synchronized void advance() {
if (pixelMap == null || pixelMap.length == 0) return;
float [] newPixelMap = new float[pixelMap.length];
for (int i=1;i<pixelMap.length;i++) {
newPixelMap[i-1] = pixelMap[i];
}
newPixelMap[newPixelMap.length-1] = addNoise();
pixelMap = newPixelMap;
}
public void run() {
while (true) {
advance();
repaint();
try {
Thread.sleep(25);
} catch (InterruptedException e) {}
}
}
private int getY (float height) {
double proportion = (1-height)/2;
return (int)(getHeight()*proportion);
}
public void paint (Graphics g) {
if (screenBuffer == null || screenBuffer.getWidth(this) != getWidth() || screenBuffer.getHeight(this) != getHeight()) {
screenBuffer = createImage(getWidth(), getHeight());
bufferGraphics = screenBuffer.getGraphics();
}
if (pixelMap == null || getWidth() != pixelMap.length) {
pixelMap = new float[getWidth()];
}
bufferGraphics.setColor(Color.BLACK);
bufferGraphics.fillRect(0, 0, getWidth(), getHeight());
bufferGraphics.setColor(Color.GREEN);
int lastX = 0;
int lastY = getHeight()/2;
for (int x=0;x<pixelMap.length;x++) {
int y = getY(pixelMap[x]);
bufferGraphics.drawLine(lastX, lastY, x, y);
lastX = x;
lastY = y;
}
g.drawImage(screenBuffer, 0, 0, this);
}
public void update (Graphics g) {
paint(g);
}
public static void main (String [] args) {
JFrame frame = new JFrame("Flicker test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new FlickerPanel());
frame.setSize(500,300);
frame.setVisible(true);
}
}
コードで問題が見つかりません。デスクトップ上でかなり滑らかに見えます。 ps。 1つのpixelMapを持ってそれを巡回バッファーとして使用し、同期化されたブロックでアクセスを保護するだけで、これをもっと効率的に行うことができます。新しい構造を作成する際には、それぞれの更新がOKである必要があります。 – Adam
+1 [sscce](http://sscce.org/)。それは私のプラットフォーム上でかなりひどく震える。 – trashgod
もう少しプレイしたことで、paintMacのデータ構造がペイント中に変更されていることが原因の可能性があります。そのため、画面のさまざまな部分の間で裂けてしまいます。ペイントメソッドの開始時にpixelmapのclone()を行うと改善されるようですが、ちらつきはまだ残っていますので、これがすべての答えではないと思います。 –