Solução de cache duplo para cintilação de JFrame em Java
causas do problema
Ao escrever um pequeno jogo Java, uso o JFrame herdado
public class flyView extends JFrame {
.....................................................................................
}
No código a seguir, escreva paint para desenhar
public void paint(Graphics graphics){
super.paint(graphics); /
drawBackGround(graphics);
moveGround(graphics);
Bird(graphics);
//update(getGraphics());
Por ser um efeito dinâmico, precisa atrasar a atualização
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();
}
}
}
A razão para este problema é simplesmente: " Usar repaint chamará a operação de limpeza no método update() e causará cintilação ."
Este princípio dinâmico da imagem pode ser entendido como: primeiro, você precisa desenhar uma imagem na janela, ao desenhar a próxima imagem, a imagem anterior será apagada, o fundo branco exibido após a limpeza e depois desenhar, mais O motivo é que a taxa de atualização do display é maior do que a frequência do código executando repintura.Após um curto período de limpeza, o fundo branco que aparece causa a aparência de cintilação.
Solução
Aqui usamos a tecnologia de buffer duplo para eliminar a cintilação da tela. O princípio é: "No fundo que precisa ser redesenhado com antecedência, armazene em cache a próxima imagem na imagem com antecedência e, em seguida, sobreponha diretamente a imagem desenhada com antecedência" Não Depois de limpar a exibição em branco na tela, não há cintilação
Portanto, o método de atualização precisa ser refatorado Este
é o método de atualização de origem
public void update(Graphics g)
{
paint(g);
}
Refatorar o método de atualização
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
}
notas
No momento da postagem, escrevi o código Java no MacOS com antecedência, mas tentei muitos métodos de atualização de refatoração e o buffer duplo ainda aparecerá piscando
. Usar o buffer duplo no Windows não pisca e não encontrei um solução para piscar no MacOS. Se houver alguma O grandalhão sabe, por favor, dê dicas, obrigado por suas críticas e correções!