2016-05-12 7 views
1

Я все еще студент. Я пытаюсь научиться рисовать мяч и двигаться сам.Почему мой мяч продолжает мигать?

Вот код:

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%, потому что

, когда я запускаю программу мяч движется вправо, но мигать для некоторых причина, и я не знаю, почему.

Это моя компьютерная проблема, или код или какая-то ошибка?

Я использую затмение Луну

+1

Когда вы поймаете свое исключение, по крайней мере распечатайте что-то, чтобы вы знали, когда что-то пойдет не так. – Gendarme

+1

Это, похоже, связано с тем, что перекрашенный шар - его нужно удалить и снова отобрать, что может иметь небольшое отставание, что приводит к миганию. –

+0

Прекрасно работает для меня. Не мигает. Я бы добавил операцию закрытия по умолчанию на вашем JFrame: http://stackoverflow.com/questions/7799940/jframe-exit-on-close-java – ManoDestra

ответ

2

Это очень классическая проблема, которую вы видите, когда обновления только с частями данных экрана вы хотите, чтобы показать.

В этом случае update(Graphics) JFrame очищает экран с помощью 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(); 
    } 
} 
} 

Это должно быть мерцать бесплатно, но все еще может быть прерывистый.

Для более плавной анимации вы обычно учитываете синхронизацию между кадрами и framedrops вместо того, чтобы просто обновлять каждые 100 мс и надеяться, что она превратит ее в своевременную перерисовку.

Смежные вопросы