Stoppen Sie das flackern in einfache Java-Animationen
Habe ich ein einfaches applet, das animiert ein Rechteck entlang der x-Achse der Leinwand. Das problem ist, dass es flackert. Ich habe versucht, Google diesem problem, aber ich wollte nicht kommen mit etwas sinnvolles oder etwas, das habe ich verstanden.
Ich bin relativ neu in Java.
Dank!
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import javax.swing.*;
public class simpleAnimation extends JApplet implements ActionListener {
Timer tm = new Timer(10, this);
int x = 0, velX = 2;
public void actionPerformed(ActionEvent event) {
if (x < 0 || x > 550){
velX = -velX;
}
x = x + velX;
repaint();
}
public void paint ( Graphics g ) {
super.paint(g);
g.setColor(Color.RED);
g.fillRect(x, 30, 50, 30);
tm.start();
}
}
**********AKTUALISIERT CODE OHNE FLIMMERN**********
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
public class simpleAnimation extends JApplet implements ActionListener
{
Graphics bufferGraphics;
Image offscreen;
Dimension dim;
int x = 3, velX = 2;
Timer tm = new Timer(10, this);
public void init()
{
dim = getSize();
offscreen = createImage(dim.width,dim.height);
bufferGraphics = offscreen.getGraphics();
}
public void paint(Graphics g)
{
bufferGraphics.clearRect(0,0,dim.width,dim.width);
bufferGraphics.setColor(Color.red);
bufferGraphics.fillRect(x,50,50,20);
g.drawImage(offscreen,0,0,this);
tm.start();
}
public void update(Graphics g)
{
paint(g);
}
public void actionPerformed(ActionEvent evt)
{
if ( x < 0 || x > 550){
velX = -velX;
}
x = x + velX;
repaint();
}
}
Habe ich dieses applet als Vorlage.
- Sie müssen double buffer.
- möglich, Duplikat der Java-Applet flackern beim laufen? (nicht jeder sieht, flackern)
- Die
paint()
ist Täter das flackern. - Swing ist double buffered standardmäßig, Sie brauchen nicht etwas besonderes zu tun.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem ist, top-level-Container wie
JApplet
nicht double-buffered. Dies bedeutet, dass, wenn es aktualisiert wird, flackert der Bildschirm wie jede Aktion direkt auf den Bildschirm.Stattdessen sollten Sie eine benutzerdefinierte Komponente erstellen, mit so etwas wie einem
JPanel
, und überschreiben Sie diepaintComponent
Methode und führen Sie Ihre custom-painting Aktionen gibt.Da Swing-Komponenten sind doppelt gepuffert, die Ergebnisse der Lack Maßnahmen gepuffert werden, bevor Sie gemalt werden, um zu dem Bildschirm, so dass es eine einzelne Aktion
Werfen Sie einen Blick auf Performing Custom Painting für mehr details
Ich immer Mühe mit diesem Konzept des "double buffering".
Hier ist mein Beispiel für das überschreiben von paint() von JApplet und eine paintComponent() eines JPanel, die verwendet double-buffering standardmäßig.
Sehe ich keinen Unterschied in der scheinbaren flackern.
Ich den code testen mit: appletviewer SimpleAnimation.java
Ist mein Konzept der "double buffering" fehlerhaft, oder meine Umsetzung, oder beides?
Was Sie jetzt tun, funktioniert wie folgt:
Also mit jedem Schritt, den Sie zuerst wischen Sie das Rechteck, und zeichnen Sie ihn dann frisch. Also das flackern - die Pixel unter dem Rechteck verändern sich von weiß zu rot zu weiß zu rot zu weiß zu rot...
Nun beobachten, dass die kleinste Menge der Gemälde, die Sie tun müssen, ist (vorausgesetzt, Rechteck bewegt sich nach rechts) dieses:
velx
Pixel auf der linken Seite WEIßvelx
pixes auf der rechten Seite ROTWenn Sie das tun, wird die animation gleichmäßig.
Computing, das kann schwierig sein, obwohl, vor allem, wenn Ihre Form ist komplizierter, als nur ein Quadrat /Bewegung ist komplexer. Das ist, wo die doppelte Pufferung ins Spiel kommt.
Mit double buffering, erstellen Sie ein Bild im Speicher, dass ist die gleiche Größe wie Ihre Leinwand. Sie malen Sie Ihre gesamte Thema dort. Dann malen Sie das Bild auf Ihrem Bildschirm auf einmal.
Wenn Sie das tun, gibt es keinen Zwischenschritt der "ganze Bildschirm WEIß ist"; somit kein flackern. Beachten Sie aber, dass Sie am Ende re-Malerei den gesamten Bildschirm statt nur der Bereich, der verändert, was nicht ideal ist. Erwägen Sie die Verwendung clipping - eine Technik, wo Sie streichen, einen vordefinierten Bereich des Bildes und nicht die ganze Sache.