如何消除动画期间出现的闪烁?

我正在通过在JApplet中制作一个小游戏来学习Java。 我的精灵动画有点问题。

这是代码:

this.sprite.setBounds(0,0,20,17); this.sprite.setIcon(this.rangerDown); for(int i = 0; i< 16;i++) { this.sprite.setBounds(this.sprite.getX(), this.sprite.getY()+1, 20, 17); this.sprite.update(this.sprite.getGraphics()); try{ Thread.currentThread().sleep(100); }catch(InterruptedException e){ } 

}

它在动画期间留下了一些闪烁。 一旦动画结束,闪烁就消失了,但它有点难看……我想我错过了一些步骤。 我使用这种方法是因为它现在提供了更好的结果,但是如果可能的话我想保持不使用AWT,而是使用Swing。

任何想法如何摆脱闪烁?

谢谢阅读。

Screenshoot (无法发布图片,抱歉)。

这不是影子。 它是你的精灵的边界。 它恰好是黑色,看起来像一个阴影。 如果你更改了精灵的数量(比如50像素,而不仅仅是1),你会看到我的意思。

要修复它,你需要做的是每次更新精灵的位置时绘制背景。 虽然这可能会产生闪烁。

正确的方法是改变绘制对象的方式。 您需要覆盖面板的paintComponent方法,然后在每次更新精灵的位置时调用重绘。

编辑:

有关基本用法,请参阅此代码示例。 注意:这不是您应该如何使用线程编写动画。 我写了这个,以向您展示paintComponent方法中的内容并编写动画线程,以向您显示您提到的“影子”已消失。 永远不要在一个线程中有一个非结束的运行循环:)

 import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; import javax.swing.JPanel; public class Test { public static void main(String[] args) { JFrame f = new JFrame("Test"); MyPanel c = new MyPanel(); f.getContentPane().add(c); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(350, 100); f.setVisible(true); } } class MyPanel extends JPanel { int x = 0; boolean toTheRight = true; public MyPanel() { new Thread(new Runnable() { @Override public void run() { while (true) { x = (toTheRight)?x+5:x-5; if (x>300) toTheRight = false; if (x<0) toTheRight = true; repaint(); try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @Override protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D)g.create(); g2.setPaint(Color.white); g2.fillRect(0, 0, getWidth(), getHeight()); g2.setPaint(Color.red); g2.fillOval(x-2, 50, 4, 4); } } 

问题是双缓冲。

在Applet中:双缓冲几乎是自动完成的。 在方法中调用repaint()而不是paint。

在Swing中,有很多方法可以做到这一点。 我通常会去BufferStrategy路线。 初始化框架时,请执行以下操作:

 JFrame frame; ... code to init frame here frame.createBufferStrategy(2); 

然后在你的绘制方法中:

 Graphics g = getBufferStrategy().getDrawGraphics(); ..code to do drawing here... g.dispose(); getBufferStrategy().show();