简体   繁体   中英

Why does my ball keep flashing?

I am still a student. I am trying to learn how to draw a ball and move by myself.

Here is the code :

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();
    }
}
}

I would say this code work 60% of it because

when i run the program the ball is moving to the right, but it keep flashing for some reason and i dont know why.

it is my computer problem , or the code or some kind of bug?

i am using eclipse luna

This is a very classic problem you see when the screen updates with only parts of the data you want it to show.

In this case, the JFrame's update(Graphics) clears the screen with a fillRect, then calls your paint(Graphics) which draws the ball with a fillOval.

If the screen updates between the fillRect and the fillOval, the ball will briefly disappear, causing the flashing (aka flickering).

The solution is double buffering, where all the graphics operations are drawn to an offscreen image, and then drawn to the window in one operation.

This is something you get for free with JPanel , so just modify your code to inherit from that instead of JFrame (this is good practice in any case). Here it is with minimal code changes:

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();
    }
}
}

This should be flicker free, but may still be jerky.

For smoother animation, you'd typically account for inter-frame timing and framedrops instead of just updating every 100ms and hoping it makes it into a timely repaint.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM