2

我正在通过在 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。

任何想法如何摆脱闪烁?

谢谢阅读。

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

4

2 回答 2

2

这不是影子。它是你的精灵的边界。它恰好是黑色的,并显示为阴影。如果你改变你移动精灵的数量(让我们说 50 像素,而不仅仅是 1)你会明白我的意思。

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

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

编辑:

有关基本用法,请参阅此代码示例。注意:这不是您应该使用线程编写动画的方式。我写它是为了向您展示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);
    }

}
于 2009-11-01T00:20:32.843 回答
2

问题是双缓冲。

在 Applets 中:双缓冲几乎是自动完成的。在您的方法中调用 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();
于 2009-11-01T05:45:10.727 回答