Animation in Canvas (Rückstände)

Status
Nicht offen für weitere Antworten.

Marcel_Handball

Bekanntes Mitglied
Hallo zusammen,
ich versuche gerade ein Applet zu programmieren, in der eine Animation, mit Hilfe der Thread-Klasse, in einem Canvas von oben nach unten "laufen" soll.

Ich hab dazu einfach mal eine "Line" verwendet, die waagerecht liegt, und dessen y-Werte sich per Schleife nach unten bewegen.
Das Problem, dass ich nun habe, ist, dass daraus ein Rechteck wird, da die Linien mit den "älteren" y-Koordinaten nicht wieder verschwindet. ( Es wurden somit viele Linien einfach untereinander gemalt).

Aber es soll sich nur eine Linie bewegen und keine Rückstände hinterlassen.
Hier, was ich bisher geschrieben habe.

Code:
import java.applet.*;
import java.awt.*;
import java.awt.event.*; 

public class ani extends Applet implements Runnable
{   Thread myThread;
    Canvas zeichenfeld=new Canvas();
    Button halt=new Button("Anhalten");
    boolean lauf=true;
    int weite=5;
    
    public void init(){
        
        setLayout(null);
        zeichenfeld.setBackground(Color.black);
        zeichenfeld.setBounds(10,10,300,300);
        add(zeichenfeld);
        
        halt.setBackground(Color.gray);
        halt.setBounds(320,10,100,25);
        add(halt);
        
        ereignisbehandlung( );
  
    }

    public void start(){
        if(myThread==null){myThread=new Thread(this); 
        myThread.start();}
    }
    
    public void run(){
        Graphics g;
        g= zeichenfeld.getGraphics( );
        while(myThread != null){
        
        for(int a=weite;a<=295; a++){
        
            g.setColor(Color.red);
            g.drawLine(5,a,200,a);
            weite=a;
            try{myThread.sleep(20);}catch(InterruptedException e){}
        }}
    }
    
    public void stop(){
        myThread.stop();
        myThread = null;
    }

    
  public void ereignisbehandlung( ) {
    halt.addActionListener( new ActionListener( ) {
      public void actionPerformed( ActionEvent e ) {
          if(lauf==true){stop(); lauf=false;}
            else{start(); lauf=true;}
      }
    } ); 
   }

}

Was muss ich verändern, um dies hinzukriegen?

Schon im Voraus vielen Dank für eure Hilfe.
 

Marco13

Top Contributor
Es gibt "fast nie" einen Grund, "getGraphics" aufzurufen

Lies dir mal
http://java.sun.com/products/jfc/tsc/articles/painting/
durch. Das entscheidende ist, dass alles, was gemalt wird, immer in der paint-Methode gemalt werden muss.

Am einfachsten erreicht man das, indem man eine Klasse von Canvas ableitet, und die paint-Methode so überschreibt, dass dort die aktuelle Linie an der richtigen Position gezeichnet wird.

Wenn du dort vorher dann den Hintergrund clearen willst, kannst du das durch
Code:
    g.setColor(Color.WHITE);
    g.fillRect(0,0,getWidth(),getHeight());
erreichen. (Aber bitte diese Zeilen jetzt NICHT einfach so ein dein Porgramm einbauen (was zwar funktionieren würde, aber "falsch" wäre))

EDIT:
Ich sehe gerade, dass du Thread.start/stop verwendest. Die sind deprecated. Wie man das "richtig" macht, steht hier
http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
Wenn daran was unklar ist, einfach nochmal nachfragen
 

Marcel_Handball

Bekanntes Mitglied
Erst einmal vielen Dank für deine Antwort !!!

Ich hab jetzt erst einmal versucht das stop-"Problem" zu verbessert:

Code:
public void start(){
        if(myThread==null){myThread=new Thread(this); 
        myThread.start();}
    }
    
    public void run(){
        thisThread = Thread.currentThread();
        Graphics g;
        g= zeichenfeld.getGraphics( );
        while(myThread == thisThread){
        
        for(int a=weite;a<=295; a++){
        
            g.setColor(Color.red);
            g.drawLine(5,a,200,a);
            weite=a;
            try{thisThread.sleep(20);}catch(InterruptedException e){}
        }}
    }
    
    public void stop(){
        myThread = null;
    }

Leider hält aber mit dieser Methode das Thread nicht mehr an, was mache ich falsch?

Marcel
 

Marcel_Handball

Bekanntes Mitglied
EDIT

... gibt es denn keine andere Möglichkeit in einem Canvas eine Animation darzustellen, als mit "ClearRect()" bzw. "FillRect()", sodass keine Rückstände zurückbleiben.

Und wie kann ich die Paint Methode dazu verwenden in das Canvas zu zeichnen ohne "getGraphics()"? Hab noch nicht allzuviel Erfahrung, deshalt muss ich so blöd fragen.

Danke für eure Antworten.
 

Marco13

Top Contributor
Für das Zeichnen der Animation mußt/solltest du eine Klasse von Canvas ableiten. UNGEFÄHR(!) so (was genau die "beste" Lösung ist, muß sich derjenige überlegen, der weiß, was dabei am Ende rauskommen soll)

Code:
class MyAnimationCanvas extends Canvas
{
    int x0, y0, x1, y1; // Endpunkte der aktuellen Linie, werden über eine set-Methode gesetzt

    public void paint(Graphics g)
    {
        g.setColor(Color.WHITE);
        g.fillRect(0,0,getWidth(),getHeight());
        g.drawLine(x0,y0,x1,y1); // Aktuelle Linie zeichnen
    }
}

....

    for (...)
    {
        myAnimationCanvas.setLineEndpoints(x0,y0,x1,y1); // Aktuelle Linie setzen
        myAnimationCanvas.repaint();
    }
(Das soll nur das Prinzip verdeutlichen!)
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben