Variablen-Abruf-Problem.

Apfelsinenkern

Aktives Mitglied
Moin,

Bei meinem Pacman-Projekt will ich versuchen den Mund des Pacman auf und zu-bewegen zu lassen, während er läuft. Um das zu machen, muss ich aber die ,,Animation" seperat als Thread laufen lassen, da sonst das Programm nicht weitergeht. Da ich aber Variablen aus der Klasse brauch, die den gegenwärtigen Standpunkt der Figur ermitteln um meine Figur an die korrekte Stelle zu zeichnen, muss ich diese aus der Klasse, die gleichzeitig den Thread startet rausholen, was bedeutet --> StackOverflowError.

Wie kann ich dieses Problem beheben?
 
Da ich aber Variablen aus der Klasse brauch, die den gegenwärtigen Standpunkt der Figur ermitteln um meine Figur an die korrekte Stelle zu zeichnen, muss ich diese aus der Klasse, die gleichzeitig den Thread startet rausholen, was bedeutet --> StackOverflowError.
Ist nicht zwangläufig so und ein StackOverflow deutet eindeutig auf einen Programmierfehler hin...

... den wir aber nur aufzeigen können, wenn wir den Code kennen.
 
Java:
Zu importierende Klassen
import javax.swing.*;
import java.awt.event.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.*;
public class Pacman extends KeyAdapter
{
   //Variablen
    public int px,py,x,y,laenge,punkte,zustand,time,i;
    private int[][] feld = new int[51][51];
    public boolean Zustand1,Zustand2,Zustand3,Zustand4,pacmanismoving;
    Thread pacpower = new Thread(new Pacpower());
    Thread pacpower2 = new Thread(new Pacpower2());
     Thread pacpower3 = new Thread(new Pacpower3());
   Thread pacpower4 = new Thread(new Pacpower4());
   Thread pacl = new Thread(new Pacmanlinks());

// Klasse die die Methode paralell zum Program ausführen soll
Java:
public class Pacmanlinks implements Runnable
{
    Pacman pacman = new Pacman();
    public void run()
    {
        pacman.zeichnePacmanl();
    }
}

Methode, die ausgeführt werden soll
Java:
  public void zeichnePacmanl()
  {
      for (x = 0; x <50; x++)
          for (y = 0; y <50; y++)
    {
      if (feld[x][y] == 31)
      {
       int t = 1;
       {
        while (t > 0)
        {   
         ZEICHENFENSTER.gibFenster().fuelleKreis(px+laenge*x+laenge,py+laenge*y+laenge,laenge,6);
         ZEICHENFENSTER.gibFenster().loescheDreieck(px+laenge*x+laenge,py+laenge*y+laenge,px+laenge*x,py+laenge*y,px+laenge*x,py+laenge*y+laenge*2);
         ZEICHENFENSTER.gibFenster().warte(time);
         ZEICHENFENSTER.gibFenster().fuelleKreis(px+laenge*x+laenge,py+laenge*y+laenge,laenge,6);
         ZEICHENFENSTER.gibFenster().warte(time);
        }
      }     
    }      
    }    
}

Methode , in der der Thread gestartet wird
Java:
 public void zeichneLevel()
    {
      for (x = 0; x <50; x++)
          for (y = 0; y <50; y++)
      {    
     //Blaue Wand     
     if (feld[x][y] == 1)
     ZEICHENFENSTER.gibFenster().fuelleRechteck(px+laenge*x,py+laenge*y,laenge,laenge,1);
     //Rote Wand
     if (feld[x][y] == 2)
     ZEICHENFENSTER.gibFenster().fuelleRechteck(px+laenge*x,py+laenge*y,laenge,laenge,4);
     //Pacman-Start
     if (feld[x][y] == 3)
     {
         ZEICHENFENSTER.gibFenster().fuelleKreis(px+laenge*x+laenge,py+laenge*y+laenge,laenge,6);
     }    
     //Pac-Man links
     if (feld[x][y] == 31)
     {
         pacl.start();
     }
     //Pacman rechts
      if (feld[x][y] == 32)
     {
     ZEICHENFENSTER.gibFenster().fuelleKreis(px+laenge*x+laenge,py+laenge*y+laenge,laenge,6);
     ZEICHENFENSTER.gibFenster().loescheDreieck(px+laenge*x+laenge,py+laenge*y+laenge,px+laenge*x+laenge*2,py+laenge*y,px+laenge*x+laenge*2,py+laenge*y+laenge*2);
     }
       //Pacman oben
      if (feld[x][y] == 33)
     {
     ZEICHENFENSTER.gibFenster().fuelleKreis(px+laenge*x+laenge,py+laenge*y+laenge,laenge,6);
     ZEICHENFENSTER.gibFenster().loescheDreieck(px+laenge*x+laenge,py+laenge*y+laenge,px+laenge*x+laenge*2,py+laenge*y,px+laenge*x,py+laenge*y);
     }
     //Pacman unten
     if (feld[x][y] == 34)
     {
     ZEICHENFENSTER.gibFenster().fuelleKreis(px+laenge*x+laenge,py+laenge*y+laenge,laenge,6);
     ZEICHENFENSTER.gibFenster().loescheDreieck(px+laenge*x+laenge,py+laenge*y+laenge,px+laenge*x,py+laenge*y+laenge*2,px+laenge*x+laenge*2,py+laenge*y+laenge*2);
     }
     //Weisses Pac-Man-Futter
     if (feld[x][y] ==4)
     ZEICHENFENSTER.gibFenster().fuelleKreis(px+laenge*x+laenge,py+laenge*y+laenge,2,8);
     //Früchte
     if (feld[x][y] == 5)
     {
     //Kirsche   
     ZEICHENFENSTER.gibFenster().fuelleDreieck(px+laenge*x+laenge-3,py+laenge*y+laenge+7,px+laenge*x+laenge,py+laenge*y+laenge+7,px+laenge*x+laenge+4,py+laenge*y+laenge-7,2); 
     ZEICHENFENSTER.gibFenster().fuelleDreieck(px+laenge*x+laenge+6,py+laenge*y+laenge+7,px+laenge*x+laenge+9,py+laenge*y+laenge+7,px+laenge*x+laenge+4,py+laenge*y+laenge-7,2);
     ZEICHENFENSTER.gibFenster().fuelleKreis(px+laenge*x+laenge,py+laenge*y+laenge+7,laenge/2-1,4);
     ZEICHENFENSTER.gibFenster().fuelleKreis(px+laenge*x+laenge+8,py+laenge*y+laenge+7,laenge/2-1,4);

    }  
    //Geist
    if (feld[x][y] == 7)
    {
        ZEICHENFENSTER.gibFenster().fuelleKreis(px+laenge*x+laenge/2,py+laenge*y+laenge/2,laenge/2,3);
        ZEICHENFENSTER.gibFenster().fuelleDreieck(px+laenge*x,py+laenge*y+laenge/2,px+laenge*x,py+laenge*y+laenge+laenge/2,px+laenge*x+laenge,py+laenge*y+laenge/2,3);
        ZEICHENFENSTER.gibFenster().fuelleDreieck(px+laenge*x,py+laenge*y+laenge/2,px+laenge*x+laenge,py+laenge*y+laenge/2,px+laenge*x+laenge,py+laenge*y+laenge+laenge/2,3);
        ZEICHENFENSTER.gibFenster().fuelleDreieck(px+laenge*x,py+laenge*y+laenge/2,px+laenge*x+laenge,py+laenge*y+laenge/2,px+laenge*x+laenge/2,py+laenge*y+laenge+laenge/2,3);
    }    
   if (feld[x][y] == 8)
    {
       //Powerball
    }    
    }
   }

So, das sind glaub ich die wichtigen Bereiche...
 
Zuletzt bearbeitet:
Sehe ich das richtig, dass du den Thread pac1 jedes mal in eine Endlosschleife wirfst und versuchst den Thread bei jeden Zeichenvorgang neu zu starten? Das wird dir ebenfalls eine Exception schmeißen. Interessanter wäre es natürlich zu wissen, wo die Exception fliegt.
 
Dann weißt du ja, wo der Fehler ist. Die Methoden rufen sich nacheinander auf, bis der Stack, der die Methodeneinsprungpunkte speichert voll ist. Das musst du verhindern.
 
Ok klingt logisch, hilft mir aber nicht viel bei meinem Problem. Ich will ja, dass er erstmal wenigstens in der Ausgangssituation sich bewegt. Aber selbst mit extends funzts ned. Ich will doch nur ne Methode innem Thread ausführen ;(
 
Beim erzeugen des Threads musst du dem die Instanz der Klasse, in der er erzeugt wird, mitgeben (wie bereits erwähnt). Das machst du mit "this":

Java:
KlasseMItThread k = new KlasseMitThread(this);
//und dann halt  das übliche. Die erste Zeile kann natürlich auch wie bei deinem Code in die zweite integriert werden
Thread t = new Thread(k);
t.start();

Dann kannst du in der Threadklasse auf die instanzierende Klasse referenzieren.

Java:
//Konstruktor
public KlasseMitThread(AeussereKlasse ak) {
ak.methodenAufruf() //oder Speicherung in einer Instanzvariable etc.
 

Zurück
Oben