问题原因
在写Java小游戏时,我使用继承了JFrame
public class flyView extends JFrame {
.....................................................................................
}
在下面的代码中,写paint进行绘制
public void paint(Graphics graphics){
super.paint(graphics); /
drawBackGround(graphics);
moveGround(graphics);
Bird(graphics);
//update(getGraphics());
因为是动态效果,需要延迟刷新
public void mainWindow(){
setBounds(700,250,288,512);
setTitle("Test");
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //
setResizable(false);
/*线程刷新实现动效*/
while(true){ //让窗口自动刷新
repaint();;
try{
Thread.sleep(180); //线程休眠180ms,控制刷新频率
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
出现这个问题的原理简而言之就是:“使用repaint会调用update()方法中的清屏操作从而导致闪烁。”
这个图像动态原理可以理解为:首先需要在窗口中绘制一张图片,在绘制下一张图片时,会清空上一张图片,清空后背景展示出的白色,接着在进行绘制,,更多的原因是显示器的刷新频率高于代码运行repaint的频率导致,在短暂的清空下,出现的白色背景导致闪烁的出现
解决方法
这里我们用到双缓存技术,来消除画面闪烁,其原理:“在预先需要重绘的背景下,提前在图片上缓存好下一张图片,再将提前绘制好的图片直接覆盖在上面”没有了清屏下空白的显示,也就没有了闪烁
因此,需要重构update方法
这是源update方法
public void update(Graphics g)
{
paint(g);
}
重构update方法
Image offScreenImage = null; //新建一张背景图
public void update(Graphics g){
if (offScreenImage == null)
offScreenImage = createImage(“画布width”,“画布height” ); //背景图的大小尺寸
Graphics gOff = offScreenImage.getGraphics();
paint(gOff); //调用paint()传入缓冲图象
g.drawImage(offScreenImage, 0, 0, null); //将缓存图像传入到 g
}
小记
截止发帖,我预先是在MacOS上写的Java代码,但是试了很多重构update方法,双缓冲还是会出现闪烁
在Windows上使用双缓冲没有闪烁,暂且没有找到MacOS解决闪烁的方法,如果有哪位大佬知道,烦请指点,感谢批评指正!