【发布时间】:2017-07-02 18:14:45
【问题描述】:
我正在使用我自己的双缓冲进行渲染循环,我没有 JPanel 而是 JFrame(据我了解 JPanel 自动双缓冲)。我的问题是,当我调用 super.paint(g) 时,它会导致我的屏幕闪烁。当我对此发表评论时,它就会消失。
ATM 我创建了一个 BufferedImage 并获取它的 Graphics2D,然后在每个渲染循环中我用纯色刷新图像并调用 repaint()。在paint 方法中,我调用super 并使用paint() 方法的图形来绘制图像。即使在渲染 1 fps 时,这也会导致我的屏幕闪烁。
public void run()
{
long startTime;
long runTime;
double residualTime = 0;
while(isRunning)
{
startTime = System.nanoTime();
**update.update();**
render.render();
runTime = System.nanoTime() - startTime;
if(runTime < 1e9/fpsTarget)
{
Double sleepTime = (1e9/fpsTarget - runTime) / 1e6;
residualTime += sleepTime % 1;
sleepTime -= sleepTime % 1;
if(residualTime > 1)
{
sleepTime++;
residualTime--;
}
try
{
sleep(sleepTime.longValue());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally
{
/*
System.out.println("\n Run time: " + runTime / 1e6);
System.out.println(" Sleep time: " + sleepTime);
System.out.println("Residual Time: " + residualTime);
*/
}
}
//fps(startTime);
}
}
public class Render
{
private Screen screen;
Graphics2D graphics;
BufferedImage image;
public Render()
{
screen = new Screen();
image = new BufferedImage(screen.getWidth(), screen.getHeight(), BufferedImage.TYPE_INT_RGB);
graphics = image.createGraphics();
}
public void render()
{
flush();
screen.setImage(image);
screen.repaint();
}
private void flush()
{
graphics.setPaint(Color.BLUE);
graphics.fillRect(0, 0, image.getWidth(), image.getHeight());
}
}
public class Screen extends JFrame
{
private BufferedImage image;
public Screen()
{
super(TITLE);
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setLocation(300, 150);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void paint(Graphics g)
{
super.paint(g);
g.drawImage(image, 0, 0, null);
}
public void setImage(BufferedImage image)
{
this.image = image;
}
我之前尝试过添加 JPanel 并通过 paintComponent() 进行渲染,但遇到了同样的问题。任何想法建议都会有所帮助!
编辑 - 已解决
在 Render.render() 方法中设置我的图像时,可能会自动调用 repaint()。然后我在导致双重刷新后立即调用 repaint() 。删除我自己的 repaint() 调用解决了这个问题。
奇怪的是,在我调用 repaint() 之前,删除 super.paint() 也解决了这个问题。任何想法为什么?
【问题讨论】:
-
“我之前尝试过添加 JPanel 并通过paintComponent() 进行渲染,但遇到了同样的问题。任何想法建议都会有所帮助!” 尝试显示minimal reproducible example使用面板。
-
不要使用
paint,而是使用paintComponent和子类JPanel而不是JFrame(将面板插入框架)。很多例子在网上很容易找到......