repaint() ruckelt

Status
Nicht offen für weitere Antworten.

Marlon

Mitglied
So, beschäftige mich nun schon seit längerem mit der Spieleprogrammierung in Java.
Zur Zeit hänge ich an einem Echtzeit Java Applet.
Mein Problem geht mir eigentlich schon was länger auf den Keks und ich bin mir sicher der ein oder andere wird bei meinem Thread sicher die Augen verdrehen.
Das Problem ist ganz einfach:
Ich male mehrere Objekte in mein Appletpanel, die alle gezeichnet werden müssen.
Ich rufe ein repaint() für jeden Bereich im Applet auf, der neugezeichnet werden muss.
Das verbraucht ziemlich viele Recourcen, wie ich bereits getestet habe und führt dazu, dass das Spiel ruckelt.
Ich habe es schon mit DoubleBuffering und der Clipping Methode versucht, aber das bringt alles nichts.
Wenn es hilft kann ich auch Code posten, aber vielleicht gibt es eine andere, bessere Methode.
Vielen Dank schonmal für Tipps!
Marlon
 
T

tuxedo

Gast
Was läuft denn in der paint Methode ab? Hast du da vielleicht verschwenderisch gecodet?

Was zeichnest du und vor allem wie zeichnest du?

- Alex
 

Marlon

Mitglied
alex0801 hat gesagt.:
Was läuft denn in der paint Methode ab? Hast du da vielleicht verschwenderisch gecodet?

Was zeichnest du und vor allem wie zeichnest du?

- Alex

ich zeichne mehrere objekte, die ihrerseits eine paint(g) methode implementieren

Code:
//paint panel
	public class MainPanel extends JPanel {	
		public void update(Graphics g) {
			paint(g);
		}
		
	    public void paint(Graphics g) {
			super.paintComponents(g);
			paintObjects(g);
	    }
	}
	
	private void paintObjects(Graphics g) {
		g.setColor(new Color(84, 43, 11));
		g.fillRect(0, 0, appletWidth, appletHeight);

		for(int i=0;i<MainController.getInstance().objectsize();i++) {	
			paintObject((VisibleObject)(MainController.getInstance().getObject(i)), g);
		}
	}

	//actually paints the objects
	public void paintObject(VisibleObject obj, Graphics g) {
		obj.paint(g);
		
		if(obj.getImage()!=null) {
			g.drawImage(obj.getImage().getImage(), obj.getXOnScreen(),
					obj.getYOnScreen(), obj.getWidth(), obj.getHeight(), this);
		}

		for(int i=0;i<obj.objectSize();i++) {
			paintObject((VisibleObject)obj.getObject(i), g);
		}
	}


private run() {
		for(int i=0;i<objectsize();i++) {
			updateObject(getObject(i));
			repaint(getObject(i).getXOnScreen()-1, getObject(i).getYOnScreen()-1,
					getObject(i).getWidth()+1, getObject(i).getHeight()+h1);
		}}

[/code]
 
T

tuxedo

Gast
Naja, bin in solchen Sachen auch nicht der optimierungsprofi. Aber vermeide möglichst "new" in Schleifen (da ständig neu gezeichnet wird ist das quasi auch ne Schleife). Das Color-Objekt könntest du einmal global anlegen statt immer wieder mit "new" neu zu machen.


- Alex
 

Quaxli

Top Contributor
Diesen Mehrfachaufruf könntest Du auch noch rauswerfen:

Code:
//paint panel
   public class MainPanel extends JPanel {   
      public void update(Graphics g) {
         paint(g);
      }
      
       public void paint(Graphics g) {
         super.paintComponents(g);
         paintObjects(g);
       }
   }

Stattdessen:

Code:
//paint panel
   public class MainPanel extends JPanel {   


       public void paintComponents(Graphics g) {
         super.paintComponents(g);
         paintObjects(g);
       }
   }


Hier färbst Du jedesmal den Hintergrund. Laß das. setBackground(...) im Konstruktor tut's auch

Code:
   private void paintObjects(Graphics g) {
      //g.setColor(new Color(84, 43, 11));
      //g.fillRect(0, 0, appletWidth, appletHeight);

      for(int i=0;i<MainController.getInstance().objectsize();i++) {   
         paintObject((VisibleObject)(MainController.getInstance().getObject(i)), g);
      }
   }


Den verstehe ich nicht ganz:


Code:
   public void paintObject(VisibleObject obj, Graphics g) {
      obj.paint(g);
      
      if(obj.getImage()!=null) {
         g.drawImage(obj.getImage().getImage(), obj.getXOnScreen(),
               obj.getYOnScreen(), obj.getWidth(), obj.getHeight(), this);
      }

      for(int i=0;i<obj.objectSize();i++) {
         paintObject((VisibleObject)obj.getObject(i), g);
      }
   }

Das sieht wie ein Mehrfachaufruf aus. obj.paint(g) sollte das Objekt malen und gut. Du prüfst aber nochmal ob ein Image vorhanden ist und malst das nochmal - was wird dann beim ersten Mal gezeichnet. Und das letzte Stück Code greift wohl auf einen Vector zu und dann werden nochmal alle Objekte gezeichnet?


Guck mal in mein Tutorial, da findest Du ein Beispiel, wie man eine komplexe Animation aufziehen könnte. Link
 

Marlon

Mitglied
Quaxli hat gesagt.:
Diesen Mehrfachaufruf könntest Du auch noch rauswerfen:
Das sieht wie ein Mehrfachaufruf aus. obj.paint(g) sollte das Objekt malen und gut. Du prüfst aber nochmal ob ein Image vorhanden ist und malst das nochmal - was wird dann beim ersten Mal gezeichnet. Und das letzte Stück Code greift wohl auf einen Vector zu und dann werden nochmal alle Objekte gezeichnet?

genauer gesagt handelt es sich hierbei um einen rekursiven aufruf. ein objekt kann in meinem spiel mehrere unterobjekte besitzen. stell dir eine kreatur vor. das ist das objekt. diese kreatur kann nun einen hut tragen. das waere dann ein unterobjekt und muss ebenfalls gezeichnet werden.
 

Quaxli

Top Contributor
Finde ich unschön gelöst, aber das ist eher subjektiv. Ich bevorzuge pro Objekt einen paint-Aufruf. Die entsprechende Logik, wenn etwas dazu gezeichnet werden muß, ist das dann bei mir in der paint-Methode des Objektes hinterlegt. Das spart dann eine weitere Schleife. Damit ist dann auch alles in einem Objekt gekapselt.
 

Marlon

Mitglied
Quaxli hat gesagt.:
Finde ich unschön gelöst, aber das ist eher subjektiv. Ich bevorzuge pro Objekt einen paint-Aufruf. Die entsprechende Logik, wenn etwas dazu gezeichnet werden muß, ist das dann bei mir in der paint-Methode des Objektes hinterlegt. Das spart dann eine weitere Schleife. Damit ist dann auch alles in einem Objekt gekapselt.

nunja, ein objekt sollte nicht unbedingt ueber seine unterobjekte bescheid wissen muessen.
so bleibt es von diesem objekt gekapselt und die unterobjekte duerfen auch in anderen objekten verwendet werden.
abgesehen davon ist mir aufgefallen, dass ich noch nicht soweit bin, dass ich unterobjekte an objekte haenge.
das heisst, die diskussion koennen wir erstmal verschieben und uns nochmal dem repaint problem widmen.

ich habe nun das double buffering getestet, so wie auf mehreren seiten im internet beschrieben.
leider hat sich an der performance nichts geaendert.
ich finde irgendwie keine loesung.
sofern auf dem bildschirm gemalt wird ruckelt es.
bei meinem kumpel flimmert es sogar stark.
auf wieder einem anderen rechner laeuft es zwar nicht ruckelig, dafuer sehr langsam...
wer weiss weiter?
 

Marco13

Top Contributor
Du machst dort den Aufruf
Code:
g.drawImage(obj.getImage().getImage(), obj.getXOnScreen(),
               obj.getYOnScreen(), obj.getWidth(), obj.getHeight(), this);
Damit wird das Bild skaliert gezeichnet. Es wäre (u.U. DEUTLICH!) schneller, wenn du das Bild nur EIN mal skalieren würdest (was kein Problem sein sollte, weil das 'obj' ja das Bild kennt, UND die Größe, die es haben muss), und dann nurnoch das fertig skalierte Bild mit
Code:
g.drawImage(obj.getImage().getTheImageThatWasScaledToTheDesiredSizeOnceInTheConstructorOfObj(), obj.getXOnScreen(),
               obj.getYOnScreen(), this);
zeichnen würdest.
 

Marlon

Mitglied
HA, stimmt, das wird ja jedesmal skaliert, wenn ich die groesse beim aufruf der drawimage funktion mit angebe.
dabei skaliere ich das doch in der tat im konstruktor!
ich habe mir dieses tutorial angeschaut und meine ganze paint funktionalitaet danach umgeschrieben.
das ist wirklich super (wenn auch sehr umstaendlich geloest mit dem zeichnen)!
es laeuft naemlich nun nicht mehr ruckelig sondern schoen gleichmaessig.
trotz allem laeuft es auch nie richtig schnell wenn ich das timedelay runterschraube. (was es jedoch tut, wenn ich ganz aufs zeichnen verzichte)
aber was solls, damit kann ich erstmal leben.
vielen dank also an alle!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Repaint flackert!!! Spiele- und Multimedia-Programmierung 1
K Flackern bei repaint Methode Spiele- und Multimedia-Programmierung 3
Y Problem mit repaint() in run() Spiele- und Multimedia-Programmierung 2
B Bilder in GUI ändern ohne repaint() Spiele- und Multimedia-Programmierung 6
M Scrolling Repaint Problem Spiele- und Multimedia-Programmierung 2
H Repaint-Problem mit Quaxlis Tutorial Spiele- und Multimedia-Programmierung 2
Steev Eigene Repaint-Logik Spiele- und Multimedia-Programmierung 17
S Animation mit repaint Spiele- und Multimedia-Programmierung 2
F Repaint Problem Spiele- und Multimedia-Programmierung 6
A Graphics2D. repaint() Spiele- und Multimedia-Programmierung 12
R Update und repaint() im ActionListener Spiele- und Multimedia-Programmierung 3
P repaint verschiebt das Bild Spiele- und Multimedia-Programmierung 2
C repaint und tempo Spiele- und Multimedia-Programmierung 4
S Spiel ruckelt trotz 50 fps Spiele- und Multimedia-Programmierung 16
M Spiel ruckelt Spiele- und Multimedia-Programmierung 8
Quaxli TileMap ruckelt Spiele- und Multimedia-Programmierung 19
Quaxli Spiel ruckelt auf neuem Rechner bzw. mit Java 6 Spiele- und Multimedia-Programmierung 13
F Das SPiel ruckelt nach einer Zeit Spiele- und Multimedia-Programmierung 19
T Java2D Spiel, beim Hinzufügen eines Bildes ruckelt das ganze Spiele- und Multimedia-Programmierung 3

Ähnliche Java Themen


Oben