[Java2D] Performance Frage

Status
Nicht offen für weitere Antworten.

Shiroi

Mitglied
Hiho, ich hätte da mal ne Performance Frage.
Ich hab da eine kleine 2D Engine geproggt, ich glaub man kann sie schon soweit eine Engine nenne *g*, die auch einigermaßen gut läuft. Nun habe ich mal mit ein paar Effekten wie Transparenz (opaque) rumgespielt und bin auch seehhrr schnell in einen kritischen Bereich gekommen, bei der die Engine das stottern begonnen hat bzw. Java es nicht mehr verkraftet hat.
Meine Idee war, die Silhouette/Schatten von einer über dem Boden schwebenden/bewegenden Wolke darzustellen.

Folgender Code wird zum "rendern" benützt. (aber etwas gekürtzt *g*)

Code:
public class Engine2D extends JComponent implements Runnable {

  public Engine2D(){
    //<..>
    ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f);
    //<..>
  }

  public void start() {
    if (thread != null) {
      return;
    }
    thread = new Thread(this);
    thread.setPriority(Thread.MIN_PRIORITY);
    thread.setName("Engine Thread");
    thread.start();
  }


  public synchronized void stop() {
    if (thread != null) {
      thread.interrupt();
    }
    thread = null;
    notifyAll();
  }


  public void run() {
    Thread me = Thread.currentThread();
    while (thread == me) {
      try {
        thread.sleep(25);
      } catch (InterruptedException e) {}
      repaint();
    }  
    thread = null;
  }

//<..>

public void paint(Graphics g) {
    if (buffer == null) {
      buffer = new BufferedImage(renderres_x, renderres_y,
                                 BufferedImage.TYPE_INT_RGB);
      offscreen = buffer.createGraphics();
    }

    offscreen.setColor(Color.black);
    offscreen.fillRect(0, 0, renderres_x, renderres_y);

    generateObjects();
    generateEnvoirnment();
    //<..> paar Strings werden auf das Bild gemalt
    Graphics2D g2 = (Graphics2D) g;
    g2.drawImage(buffer, 0, 0, renderres_x, renderres_y, this);
  }

  private void generateObjects() {
  
    //<..> Kurzer Algorithmus zur Berechnung des sichtbaren Bereiches, so dass nur dieser gerendert wird.

    aktfx = fpx1; // Feldposition. Die Felder sind in einem xy Array gespeichert
    aktfy = fpy1;
    aktpx = px1; // Koordinate des Feldes in Pixel
    aktpy = py1;

    while (aktpy <= ry2) {
      while (aktpx <= rx2) {
        if (aktfx >= 0 && aktfy >= 0 && aktfx <= max && aktfy <= max) {
          if ((obj[aktfx][aktfy]) != null) {
            objekt = obj[aktfx][aktfy]; // Objekte (Häuser, Bäume, etc.)
            offscreen.drawImage(objekt, (aktpx - 30) - rex,
                                (aktpy - 30) - rey, 60, 30, this);
          } else {
            objekt = ground[aktfx][aktfy]; // Untergrund (Wiese)
            offscreen.drawImage(objekt, (aktpx - 30) - rex,
                                (aktpy - 30) - rey, 60, 30, this);
          }
        }
       //<..> Neue Position wird berechnet für das nächste Objekt in X Richtung
      }
      //<..> Neue Position wird berechnet für das nächste Objekt in Y Richtung
    }
  }

 private void generateEnvoirnment() {
    if (env == 1) {
      offscreen.setComposite(ac);
      for (int i = 0; i <= renderres_y/60 + 1; i++) {
        for (int j = 0; j <= renderres_x/60 + 1; j++) {
          offscreen.drawImage(sky, j * 60, i * 60, this);
        }
      }
      offscreen.setComposite(AlphaComposite.SrcOver);
    }
  }

//<..>

}

Mein Problem liegt in der Methode generateEnvoirnment(), welche eigentlich nur dieses Provisorische gif
sky.gif
aneinander Reiht und es einbissel durchsichtig macht, was normal ja nicht das große Problem sein sollte zum rendern.... aber es geht gewaltig auf die Performance!

Wer es testen will --> Hier ist ne kleine Demo von der Engine. Ach so, achtet nicht auf die FPS *ggggg*

Um die Wolken zu aktivieren, müsst ihr einfach "c" drücken und um zu scrollen müsst ihr die Pfeiltasten benützen. Beenden mit "ESC".

Im Prinzip klatsch ich nur noch mal ein Layer drauf, der eben transparente Stellen hat und Durchsichtig ist. Wer hätte einen Lösungsvorschlag wie man das auch anders realisieren könnte? Hab es auch schon mit einer Textur versucht, die ich auf ein Rechteck der Größe des zu rendernden Bereiches klatsche, was aber noch schlechter ging *g* Und wie könnte ich noch das rendern von dem generateObjects einbissel tunen? Denn beim Scrollen wirkt es einwenig verzerrt, was mir nicht so ganz gefällt.
Wie jeder sehen kann, der schon mal Caesar III gezockt hat, habe ich mir diese Engine zum Vorbild genommen ^^ Darum auch noch vorübergehend die Caesar II Grafiken und dort habe ich absolut nie so eine Verzerrung feststellen können... da frage ich mich, wie die das angestellt haben :s
Zur Info, der im generateObjects() ausgelassene Quellcode ist so minimal, dass er so gut wie keinen Effekt auf die Performance hat, da dort nur einfache Modulo Befehle ausgeführt werden.

Ich hoffe mir kann jemand mit meinen zwei Fragen weiterhelfen 🙂

mfg DaAngel

Edit: LOL .. hatte da ein Fehler in dem generateEnvironment() ... welcher vielleicht der Übeltäter war... muss es kurz testen und dann lade ich die neue Demo hoch...
Edit2: Ok es lag daran... sorry... aber tortzdem hätte ich gern noch paar Tipps, wie man das alles noch einbischen beschleunigen könnte und wie evtl. das verzerren beim scrollen weg geht und wie man den Effekt von "runden" Kanten bei einem Image hinbekomme, denn die Wolken sind immer einbissel eckig (bei den Test Wolken sowieso *g*), da es ja bei einem gif nicht teilweise durchsichtige Stellen gibt, sondern nur komplett durchsichtig oder ganricht :/ oder?
 
wo grade von performance gesprochen wird...

korrigier mich, vl. weißt du es besser, aber hilft es wenn du den thread selber schreibst?
extend Thread mein ich?

so hab ichs nämlich gemacht
 
Hab' mir die Demo runtergeladen.
1. Frage: Warum hast Du das in eine EXE Datei umgewandelt? ???:L
2. Frage: Warum kommt bei mir nur ein grauer Bildschirm? Auch "c", Esc und die Pfeiltasten bringen keine Verändernung. 🙁
 
bei mir gehts auch nicht...

und du hast die bildchen nicht zufällig von caesar 3 geklaut??
 
Also, das mit dem grauen Hintergrund ist mir auch ein Rätsel. Aber dieser Fehler kommt nur in der Exe, im "richtigen" Spiel geht es und nicht bei jedem ist der Bildschrim nur grau. Auf dem PC von meinem Bruder und bei meinem Kumpel von mir geht es ohne Probs. Es wurde jetzt schon einiges wieder gemacht, evtl. bring ich dem nächst nochmal ne Demo raus. Ja, die Bilder sind von Ceasar III, hab ich auch in meinem ersten Post geschrieben.. glaub ich *g* Die benütze ich nur vorrübergehend, um mal zu schaun wie es mit ner gescheiten Grafik aussieht, aber wir werden noch eigene Bilder machen, das ist ja selbstverständlich ^^ Ach so, wegen der Exe, ja ich werde es das nächste Mal als Jar machen.

@ Gast: Na ja, bei extends hab ich ja schon das JComponent drinnen, von daher muss ich den Thread mit Runnable machen.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben