Tôi đang viết một ứng dụng java cần cuộn một dạng sóng trơn tru trên màn hình. Tôi đã dành nhiều lứa tuổi đi qua các hướng dẫn khác nhau để tìm ra cách làm cho hoạt ảnh này mượt mà nhất có thể. Theo như tôi có thể thấy tôi đã làm tất cả những thứ bình thường để loại bỏ nhấp nháy (vẽ ra bộ đệm ngoài màn hình và hiển thị trong một bước, cộng với việc cập nhật để màn hình không bị xóa), nhưng hoạt ảnh của tôi vẫn nhấp nháy và màn hình có vẻ như nó đang bị xóa trước mỗi lần cập nhật.Làm thế nào để loại bỏ hoạt ảnh java nhấp nháy
Tôi chắc chắn có điều gì đó cơ bản (và có thể là đơn giản) tôi bị thiếu, nhưng tôi không có ý tưởng. Tôi sẽ đăng một lớp dưới đây minh họa vấn đề. Bất kì sự trợ giúp nào đều được đánh giá cao.
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);
}
}
Tôi không thể tìm thấy bất kỳ sự cố nào với mã của bạn. Trông khá trơn tru trên máy tính để bàn của tôi. ps. Bạn có thể làm điều này hiệu quả hơn nhiều bằng cách chỉ có một pixelMap và sử dụng nó như một bộ đệm tuần hoàn, và bảo vệ quyền truy cập vào nó bằng một khối đồng bộ. Vì nó là viết tắt của việc tạo ra một cấu trúc mới mỗi bản cập nhật nên được OK. – Adam
+1 cho [sscce] (http://sscce.org/). Nó shimmers khá nặng trên nền tảng của tôi. – trashgod
Có chơi nhiều hơn một chút có vẻ như một số vấn đề có thể là do cơ sở hạ tầng pixelMap đang được sửa đổi trong quá trình vẽ, vì vậy tôi đang rách giữa các phần khác nhau của màn hình. Làm một bản sao() của pixelMap ở đầu của phương pháp vẽ có vẻ để cải thiện mọi thứ, nhưng nhấp nháy vẫn còn đó vì vậy tôi không nghĩ rằng đây là toàn bộ câu trả lời. –