2016-05-12 7 views
1

Ich bin immer noch ein Student. Ich versuche zu lernen, wie man einen Ball zeichnet und sich selbst bewegt. HierWarum blinkt mein Ball?

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

ich diesen Code Arbeit 60% davon sagen würde, weil

, wenn ich starten Sie das Programm der Ball nach rechts bewegt, aber es halten für einige blinken Grund und ich weiß nicht warum.

ist es mein Computerproblem oder der Code oder irgendeine Art von Fehler?

Ich bin mit Eclipse luna

+1

Wenn Sie Ihre Ausnahme fangen, zumindest etwas ausdrucken, damit Sie wissen, wenn etwas schief geht. – Gendarme

+1

Dies scheint der Fall zu sein, wenn der Ball neu gestrichen wird - er muss entfernt und erneut gerendert werden, was eine leichte Verzögerung haben kann, was zu einem Blinken führt. –

+0

Funktioniert gut für mich. Kein Blinken. Ich würde jedoch einen Standard schließen Operation auf Ihrem JFrame hinzufügen: http://StackOverflow.com/Questions/7799940/Jframe-Exit-on-Close-Java – ManoDestra

Antwort

2

Dies ist ein sehr klassisches Problem, das Sie sehen, wenn die Bildschirm-Updates mit nur Teile der Daten, die Sie wollen, dass es zu zeigen.

In diesem Fall löscht der JFrame update(Graphics) den Bildschirm mit einem fillRect und ruft dann Ihren paint(Graphics) an, der den Ball mit einem fillOval zeichnet.

Wenn der Bildschirm zwischen dem fillRect und dem fillOval aktualisiert wird, verschwindet der Ball kurz und verursacht das Blinken (aka flackern).

Die Lösung ist die doppelte Pufferung, bei der alle Grafikoperationen auf ein Offscreen-Bild gezeichnet und dann in einem Vorgang in das Fenster gezeichnet werden.

Dies ist etwas, das Sie kostenlos mit JPanel bekommen, also ändern Sie einfach Ihren Code, um von diesem anstelle von JFrame zu erben (das ist in jedem Fall gute Praxis). Hier ist es mit minimalen Code-Änderungen:

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

Dies sollte flimmerfrei sein, kann aber immer noch ruckartig sein.

Für glattere Animationen würden Sie normalerweise Inter-Frame-Timing und Framedrops berücksichtigen, anstatt alle 100 ms zu aktualisieren und zu hoffen, dass es zu einem zeitgemäßen Repaint wird.