# Flackern bei Animationen



## Javius (16. Jul 2016)

Hallo,
ich habe ein kleines Problem bezüglich eines Spiels, was ich programmieren möchte. Ich bin noch bei den Anfängen, aber schon dort ist ein Problem aufgetreten. Im Endeffekt soll der Hintergrund permanent von oben nach unten durchlaufen während ein Bild im Vordergrund (erstmal noch) stillstehend zu sehen ist, d.h. ich will eine Art aufwärtsbewegung simulieren. Die Hintergrund-Animation funktioniert, nur das vordere Bild flackert wie verrückt. Ich hoffe mir kann jemand helfen und bedanke mich im Voraus schonmal für alle nützlichen Antworten. Hier der Code:

```
package space.adventure.org;
   import javax.imageio.ImageIO;
import javax.swing.*;
   import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
   public class Graphic extends JFrame implements Runnable{
     Thread textticker;
     int a=10;
     int b=0;
     int c=1;
     int d=-800;
     int e=5;
     public Graphic(){
       this.setSize(800,800);
       this.setLocation(100,100);
       this.setTitle("Space Adventure");
       this.setVisible(true);
       textticker=new Thread(this);
       textticker.start();   
       
         for (d=-800; d<=800;d+=2){
           if(d>=799) {
             d=-800;
           }
           try {
             Thread.sleep(10);
           } catch (InterruptedException e) {
             e.printStackTrace();
           }
           repaint();
           }}
     public void run() {
       while (c==1){
       if (b==0){
       for (a=0; a<=800;a+=2){
         if(a>=799) {
           a=-800;
         }
         try {
           Thread.sleep(10);
         } catch (InterruptedException e) {
           e.printStackTrace();
         }
         
         repaint();
         b=1;
         }}
       else{
         for (a=-800; a<=800;a+=2){
           if(a>=799) {
             a=-800;
           }
           try {
             Thread.sleep(10);
           } catch (InterruptedException e) {
             e.printStackTrace();
           }
           repaint();
           }}
       }
     }   
     public void update(Graphics g){
         paint(g);
        }
     public void paint(Graphics g){     
         File f= new File("resources/space.jpg");
         Image Bild=Toolkit.getDefaultToolkit().getImage(f.getAbsolutePath());
         this.prepareImage(Bild, this);
         if(Bild!=null){
           g.drawImage(Bild, 0, a, this);
           
             File j= new File("resources/racet.png");
             Image Bild3=Toolkit.getDefaultToolkit().getImage(j.getAbsolutePath());
             this.prepareImage(Bild3, this);
             if(Bild3!=null){   
               g.drawImage(Bild3, 400, 600, this);
               
           File n= new File("resources/space2.jpg");
           Image Bild2=Toolkit.getDefaultToolkit().getImage(n.getAbsolutePath());
           this.prepareImage(Bild2, this);
           if(Bild2!=null){             
             g.drawImage(Bild2, 0, d, this);   
         }
     }
     }}
   }
```


----------



## JCODA (16. Jul 2016)

Überschreibe kein update() sondern schreibe als erste Zeile in die paint()
super.paint(g)

Tipp: Normalerweise erbt man nicht von JFrame sondern von einem JPanel und zeichnet dort in der paintComponent()-Methode.

Oh und zudem: Lasse die Schleife im Konstruktor weg. Mit dem Thread.sleep. Dafür brauchst du wohl einen eigenen Thread.

Nächster Tipp: Bennene deine Variablen anders! So kann niemand erkennen was a,b,c,d heißen soll...


----------



## Javius (16. Jul 2016)

Ok. Vielen Dank, ich werds mir merken.


----------



## Javius (16. Jul 2016)

Kleines Problem: Ich habe jetzt einen eigenen Thread gemacht, aber es wird nun ein Problem bezüglich der repaint()-Methode angezeigt: The method repaint() is undefined for the type Thread1


----------



## Javius (16. Jul 2016)

Obwohl ist doch kein Problem, ich könnts auch einfach weglassen. Jetzt flackert aber der Hintergrund stark


----------



## Flown (20. Jul 2016)

Sauber würde eine Tickerimplementierung so aussehen:

```
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Test {
  
  public static void main(String... args) {
    SwingUtilities.invokeLater(Test::new);
  }
  
  public Test() {
    JFrame frame = new JFrame("Ticker");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationByPlatform(true);
    frame.setSize(200, 80);
    StringTicker ticker = new StringTicker("My String");
    frame.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent e) {
        super.windowClosing(e);
        ticker.stop();
      }
    });
    frame.add(ticker);
    
    frame.setVisible(true);
  }
}

class StringTicker extends JComponent {
  private static final long serialVersionUID = -48014358197943020L;
  
  private final String text;
  private int x;
  
  private final Timer timer;
  
  public StringTicker(String text) {
    this.text = text;
    x = 0;
    timer = new Timer(20, e -> {
      x++;
      if (x > getWidth()) {
        x = 0;
      }
      repaint();
    });
    timer.start();
  }
  
  public void stop() {
    timer.stop();
  }
  
  @Override
  protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (g instanceof Graphics2D) {
      ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    }
    g.drawString(text, x, getHeight() / 2 + g.getFontMetrics().getHeight() / 2);
  }
}
```


----------



## Javius (20. Jul 2016)

Vielen Dank. Ich habe aber schon eine andere Möglichkeit gefunden, mein Problem zu lösen. 
Grüße


----------

