# Thread und jpanel-paintcomponent kombinierbar??



## Stormblade (2. Nov 2012)

Hallihallo, 

ich bin seit einigen Tagen dabei Super-Mario zu programmieren. Mit einiger Hilfe aus dem Forum hier bin ich schon relativ weit gekommen, doch langsam komme ich zu dem Punkt, da ich einsehen muss, dass die performance sehr leidet wenn ich mehr und mehr objekte berechnen lasse.

Ich dachte mir, dass ich die Performance wieder erhöhen kann indem ich einzelne Objekte, wie zum beispiel mario und gumbas, sowie schildkröten und feuerbälle als einzelne Threads laufen lassen könnte.
Doch irgendwie ist das ganze nicht so einfach wie ich dachte. Wenn ich den zeichenvorgang meiner Objekte von der paintComponent-methode, in die jeweilige Thread-Klasse verschieben möchte, dann seh ich auf meinem schirm nix mehr, da das Graphics g nicht so leicht übergebbar is oder so. 
Also frage ich, ob ich trotzdem meine Objekte als Thread haben kann, oder ob das einfach nicht funktioniert???


----------



## TKausL (2. Nov 2012)

Hallo.

Für jeden Entity einen eigenen Thread schreiben ist nicht sehr sinnvoll, bringt nur Probleme.
Vieleicht zeigst du uns einfach mal so deine Main-Schleife welche updated und rendert.


----------



## Stormblade (2. Nov 2012)

Hm, ok, also ich hab meine Klasse GamePanel:

```
public class GamePanel extends JPanel{

  Entity mario, gumba, schildkröte;
  MotionSimulator motion;

  public GamePanel(){
    super();
    mario = new Entity();
    gumba = new Entity();
    schildkröte = new Entity();
  }

  public void paintComponent(){
    super.paintComponent();
    mario.drawEntity(g);
    Thread.sleep(50);             //in echt mit try und catch ausgeschrieben...
    repaint();
}
```
Und hier meine Entity-Klasse:

```
public class Entity{
  int x, y, z;
  Graphics g;
  MotionSimulator motion = new MotionSimulator();
  Umgebungsscanner scanner = new Umgebungsscanner();

  public void drawEntity(Graphics g){
    scanner.scanEnvironment();
    motion.forHumanPlayer();
    scanner.setPosition(motion.getx(), motion.gety(), motion.getvy())   // die werden im scanner verrechnet
    g.drawImage(img, motion.getx(), motion.gety(), 50, 50, null);
  }
}
```

Sodele, das is jetz nur auf die schnelle eine sehr sehr abgespeckte version meines programmes. Graphics g wird hier vom GamePanel aus an die Entity-Klasse übergeben, das funktioniert soweit. Doch ich habe es noch nicht geschafft, die Entity-klasse in einen Thread umzubauen, der dann funktionieren würde...


----------



## TKausL (2. Nov 2012)

```
public void paintComponent()
```

Was ist das? Wenn du die Klasse überschreiben willst musst du natürlich auch das Graphics annehmen mit dem du dann arbeitest.

Per Thread kannst du ja dann repaint() aufrufen.


----------



## Stormblade (2. Nov 2012)

ups, das mit dem (Graphics g) hatte ich beim schreiben dieses themas vergessen ;D In meinem Programm isses natürlich drin. Ich versuch jetzt einfach mal ohne Threads weiter zu machen, das erspart mir einiges umdenken


----------



## Marco13 (2. Nov 2012)

Falls das eine "abgespeckte" :autsch: Version der "echten" paintComponent war: Darin sollte man NICHT sleep und NICHT repaint aufrufen!!!


----------



## Stormblade (3. Nov 2012)

Lol, kein repaint() in der paintComponent??? Das mach ich schon immer so, wie sonst sollte ich veranlassen, dass das zeug neu gezeichnet wird??? Das haben mir hier schon leute empfohlen und funktioniert auch vorzüglich


----------



## Marco13 (3. Nov 2012)

Ja, es wird ein Haufen Unfug gepostet (und ich habe das Gefühl, dass es mehr wird). Repaint in der paintComponent aufzurufen, ist 
[SPOILER="Klicke den Button, wo 'Weiterlesen' drauf steht]Klicke den Button, wo 'Schließen' drauf steht[/SPOILER]


----------



## Stormblade (3. Nov 2012)

dann sag mal please an welcher stelle man repaint macht...


----------



## Melfis (3. Nov 2012)

Im Controller des Spiels.


----------



## Stormblade (3. Nov 2012)

immer eure kurzen antworten   "im controller des spiels" heißt für mich jetzt, dass ich in der main-methode in meiner Hauptklasse ne whileschleife habe, in der drinsteht: GamePanel.paintComponent.repaint(); 
Habe ich das richtig interpretiert?


----------



## Marco13 (3. Nov 2012)

Ja, in etwa. Üblicherweise gibt es in so einem ("einfachen") Spiel mindestens einen "Game Thread", der sich um den allgemeinen Spielablauf kümmert, wie z.B. die Bewegung der Figuren. Die Bewegung der Figuren hängt dabei auch davon ab, wie lange ein "Schritt" in dem Spiel dauert. GANZ grob ist der Ablauf dabei sowas wie

```
long previousTime = System.nanoTime();
while (!gameFinished)
{
    long currentTime = System.nanoTime();
    long passedTime = currentTime - previousTime;
    moveObjectsAccordingTo(passedTime);
    gui.repaint(); <- Da isses
    // Evtl.
    Thread.sleep(aFewMs); 
}
```
Schau auch mal in http://www.java-forum.org/spiele-multimedia-programmierung/54795-quaxli-2d-spiele-tutorial.html


----------



## Stormblade (3. Nov 2012)

Das is doch ma ne Antwort, die mich wirklich weiterbringt  Das Tutorial werd ich mir mal auf jeden Fall anschaun


----------



## Empire Phoenix (6. Nov 2012)

Und aFewMs wüde sich aus zb 50ms - passedTime ergeben, wenn man will das die logic das spiels fest in 50ms schritten abläuft, egal wie schnell oder langsam der pc. Und egal wie lange die berechnungen brauchen (ausnahme wenn langsamer als 50ms)


----------



## GameLoops! (6. Nov 2012)

Hier Game loops! - Java-Gaming.org gibt es zB noch mehr Infos über Gameloops und was man eher nicht tun sollte


----------

