我正在通过在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(无法发布图片,抱歉)。
答案 0 :(得分:2)
这不是影子。它是你的精灵的边界。它恰好是黑色,看起来像一个阴影。如果你更改了精灵的数量(比如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);
}
}
答案 1 :(得分:2)
问题是双缓冲。
在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();