# Programmauslastung zu hoch



## Loki87 (24. Aug 2010)

Hallo,

Es gehört sich vielleicht nicht, als ersten Post im Forum direkt Fragen zu stellen, aber irgendwie muss man ja nen Grund finden, sich anzumelden .

Die Situation:
Ich arbeite an einem 2D Shooter, der angesichts des frühen Stadiums bereits gut läuft. Das Problem dabei ist aber, dass die Prozessorauslastung bedeutend zu hoch ist. Laut meinen Tests liegt dies nicht an Endlosschleifen, irgendwelchen ungebremsten Threads oder dergleichen, sondern offenbar an der Art der Darstellung, insbesondere des Labels, welche die Objekte (Gegenstände, Gegner) beinhält. Da jeder Gegner einen eigenen Thread darstellt, und somit unabhängig sein eigenes JLabel kontrolliert, muss das Gesamtbild offenbar zu oft neugezeichnet werden. Allerdings scheint das Problem auch bei vielen unveränderten JLabels aufzutreten. Ich weiß daher einfach nicht, woran ich speziell arbeiten muss, um das Problem zu lösen =/. Ich weiß nichtmal, ob es wirklich daran liegt. Ich hoffe, ihr könnt mich da mit der Nase ein wenig in das Problem stupsen.

Anmerkung: Wie sicher bereits erkennbar ist, habe ich nicht eine paint(),paintComponent() oder ähnliche Zeichenmethode überschrieben. Ich hatte zu Beginn keine Ahnung von Grafiken in Java, und wollte selber herausfinden, zu welchen Problemen welche Vorgehensweise führt. Das hat bis jetzt auch gut geklappt, nur hier komme ich nicht weiter.

Ich hoffe, ihr könnt und wollt mir da weiterhelfen. =)
Der aktuelle Stand des Spiels ist hier zu finden, da kriegt man auch nen guten Eindruck, was ruckelt und Ressourcen verbraucht. Der gesamte Code erstreckt sich im Moment auf über 3000 Zeilen, daher würde ich Auszüge posten, falls gewünscht.

Achja, falls jemand nicht gerne Blut sieht (Obwohl das im Moment eigentlich ziemlich billig aussieht), sollte den Link nicht öffnen 

Gruß,
Loki87


----------



## Teemperor (24. Aug 2010)

Das heißt du hast für jeden Gegner ein eigenes JLabel?  Wieso kannst du nicht einfach nur die Images der Gegner auf ein Panel zeichnen?


```
try
		{
			System.setProperty("sun.java2d.opengl", "true");
		}
		catch(SecurityException e)
		{
			System.err.println("Couldn't enable OpenGL-Pipeline:");
			e.printStackTrace();
		}
```

Versuch mal das am Anfang deiner main-Methode einzufügen, das aktiviert die OpenGL-Pipeline für Java2D. Das hat mir zumindestest geholfen als ich auf JPanels gezeichnet habe. 

PS: Oh und ich frage mich du dein Leute drehst? Ich arbeite im Moment an nem ähnlichen Spiel und bei mir ist das Drehen ziemlich performant :autsch:

EDIT: Wenn ich Mist rede finde ich es schön wenn man mich verbessert, ich bin noch ein Anfänger :rtfm:


----------



## Loki87 (24. Aug 2010)

Hallo,

Das mache ich nicht, weil ich am Anfang nicht darauf gekommen bin, das zu machen, und ich jetzt im Nachhinein nicht mehr hinkriege ^^.
Ich hab zuerst für jede Drehung ein eigenes Bild gehabt, dann aber festgestellt, dass es per AffineTransform genauso schnell geht, aber natürlich weitaus weniger Speicher verbraucht ^^.


----------



## Teemperor (24. Aug 2010)

Hat es 2 mal abgeschickt, bitte löschen!


----------



## Teemperor (24. Aug 2010)

Hilft mein Code irgendwas? 

Ach so, schlechte Design-Entscheidung :autsch:

Mein Code um das gedrehte Bild zu erzeugen sah aus:


```
BufferedImage rotateImage(BufferedImage src) {
		if(isRotated()||isAnimated()) //Uberprueft ob die Figur seit dem letzten Rendering ein
		{                                      //andere Animation oder sich gedreht hat
        
			Graphics2D g = (Graphics2D) rotatedImage.createGraphics(); //altes Bild die Graphic nehmen
			g.setBackground(Sprites.trans); //Transparenz als hintergrund
			g.clearRect(0, 0, getw(), geth()); //Leeren
	        g.setTransform(  //Drehen
	        		AffineTransform.getRotateInstance(
	                Math.toRadians(rotation),
	                src.getWidth() / 2,
	                src.getHeight() / 2)
	                );
	        
	        g.drawImage(src, 0, 0, null); //Aufs Bild zeichnen
	        g.dispose();                        
	        return rotatedImage; //Zurueckgeben
		}
        //wenn nicht animiert oder rotiert altes Bild zeichnen
        return rotatedImage;
    }
```


----------



## Loki87 (24. Aug 2010)

So war Meiner auch in etwa aufgebaut

Edit:
Ich habe den Code mal ein wenig verändert:
- Änderungen in Sachen Position und Icon der Labels wird jetzt diskret und nicht kontinuierlich geändert
- Soeine Art Bilderbibliothek wurde eingeführt, welche die wichtigsten Rotationen (In meinem Fall wenn Winkel%45==0) speichert, sodass diese nicht jedesmal neu erstellt werden müssen

Diese Änderungen haben die Prozessorauslastung gut halbiert, aber 20-30% sind immernoch zuviel =/


----------

