为什么我的球会一直闪烁?

时间:2016-05-12 18:13:28

标签: java

我还是学生。我正在努力学习如何自己画球和移动。

以下是代码:

import javax.swing.*;
import java.awt.*;

public class Ball extends JFrame
{
int x = 50;
int y = 50;
int rad = 30;

Ball(){ 
    setSize(500,500);
    setTitle("Ball");
    setVisible(true);
}

void move()
{
    if (x < getWidth() - rad){
        x = x + 1 ;
    }
    try
    {
        Thread.sleep(100);
    }
    catch( Exception e)
    {           
    }
}

public void paint( Graphics g)
{
    super.paint(g);
    g.fillOval(x,y,rad,rad);
}
public static void main(String args[])
{
    Ball b = new Ball();
    while(true){
        b.move();
        b.repaint();
    }
}
}

我会说这段代码的工作量是60%,因为

当我运行程序时,球向右移动,但由于某种原因它会一直闪烁,我不知道为什么。

这是我的电脑问题,还是代码或某种错误?

我正在使用eclipse luna

1 个答案:

答案 0 :(得分:2)

这是一个非常经典的问题,当屏幕更新时只会显示您想要显示的部分数据。

在这种情况下,JFrame的update(Graphics)会使用fillRect清除屏幕,然后调用您的paint(Graphics),其中使用fillOval绘制球。

如果屏幕在fillRect和fillOval之间更新,球会短暂消失,导致闪烁(也就是闪烁)。

解决方案是双缓冲,其中所有图形操作都被绘制到屏幕外图像,然后在一次操作中绘制到窗口。

这是JPanel免费获得的内容,因此只需修改代码即可继承而不是JFrame(这在任何情况下都是很好的做法)。这是最小的代码更改:

import javax.swing.*;
import java.awt.*;

public class Ball extends JPanel
{
int x = 50;
int y = 50;
int rad = 30;

void move()
{
    if (x < getWidth() - rad){
        x = x + 1 ;
    }
    try
    {
        Thread.sleep(100);
    }
    catch( Exception e)
    {           
    }
}

public void paint( Graphics g)
{
    super.paint(g);
    g.fillOval(x,y,rad,rad);
}
public static void main(String args[])
{
    Ball b = new Ball();
    JFrame frame = new JFrame();
    frame.add(b);
    frame.setSize(500,500);
    frame.setVisible(true);

    while(true){
        b.move();
        b.repaint();
    }
}
}

这应该是无闪烁的,但可能仍然是生涩的。

为了使动画更流畅,您通常会考虑帧间时序和帧数,而不是每100ms更新一次,并希望它能够及时重新绘制。