Optimierung bei Spielen

L

Lucid85

Neues Mitglied
0
hallo, ich bins mal wieder :thumbup:

folgendes: ich habe mal wieder ein kleines spiel geschrieben und es läuft auch so, wie ich es mir vorstelle - eine art space invaders. allerdings wird das spiel seeeehr langsam, wenn viele aliens kommen - und das, obwohl meine berechnungen gar nicht so kompliziert sind...

gibt es irgendwelche generellen tipps, was man beachten kann, um spiele zu optimieren? bzw. gibt es gute tools, mit denen man z. b. den ram verbrauch messen kann?

danke schonmal :)

ps: ich verwende keinerlei bibliotheken, nur das standard androíd.graphics package und eigene berechnungen :winki:
 
Hallo,
mit einer der wichtigen Faktoren ist die Framerate.
Ansonsten sind Darstellungen, die Alpha-Werte aufweisen, meist rechenintensiv.
Wie loopst du durch deine Objekte? foreach ist meist deutlich schneller als die normale for...
Bei Kollisionsberechnungen kann man auch eine Menge Rechenleistung verbraten, bzw. sparen, wenn man die zu prüfenden Objekte vorher in eine Art "Rasterung" unterteilt. Ist aber schon recht kompliziert.

Jo, gibts.
Using DDMS | Android Developers
https://developer.android.com/tools/debugging/debugging-memory.html

Oder halt gleich auf OpenGL umsteigen. Aber das ist von dem Schwierigkeitsgrad halt nochmal eine ganz andere Liga^^
 
ui_3k1 schrieb:
Hallo,
Wie loopst du durch deine Objekte? foreach ist meist deutlich schneller als die normale for...

nehme iteratoren - ist da foreach auch schneller?
 
Nein, denn foreach arbeitet mit iteratoren.

Der Geschwindigkeitsvorteil von foreach bzw Iteratoren hängt von der Art der List ab (Set bietet zwar auch einen Iterator, aber nicht die get(n) Methode, daher kann man da ohnehin nur iterieren):

auf einer ArrayList gibt es (fast) keinen Unterschied (laut javadoc ist da der for-loop sogar geringfügig schneller), aber bei einer LinkedList ist ein Iterator deutlich schneller, denn obgleich die LinkedList eine Methode get(n) anbietet, um das 'n.te' Object zu bekommen, ist das nur in der Form möglich, dass sie von den dem '1.ten' Object beginnend n mal die next() Operation ausführt.

Das führt bei einem Loop über n Objekte zu (n²+n)/2 next() Operationen.

Ob man in einer List die get(n) Methode nutzen sollte, oder es lassen sollte, sieht man daran, dass die List das Interface 'java.util.RandomAccess' erfüllt
 
Danke für die genaue Beschreibung, so detailliert war ich nicht mal im Bild...
Allerdings habe ich die Erfahrung des Performance-Schubs bei einer ArrayList gemacht und zwar richtig krass... Komisch..
 
Verwendest du Threads für die Berechnung der Gegner? Wenn ja, wieviele? Es kann z.B. deutlich schneller sein, einen Thread zu haben, der in einer Schleife alle Gegnerbewegungen berechnet, als einen eigenen Thread für jeden Gegner. Denn das Wechseln eines Threads ist relativ Performance-intensiv.

Worauf zeichnest du? Auf eine normale View mit onDraw() oder SurfaceView? Letztere ist im Normalfall besser geeignet für Spiele.

Ausserdem solltest du alle Bilder nur einmal laden, z.B. beim Start. Es wäre schlecht, bei jedem Schleifendurchlauf wieder alle Bilder zu laden, weil das dann immer viel Zeit braucht.
 
ja, ich benutze surfaceview mit einem thread, in welchem allles in einer while-schleife berechnet und gezeichnet wird. parallel dazu habe ich immer nur noch einen anderen thread laufen, der die zeit bis zum nächsten "bonus-drop" berechnet.
die bilder lade ich auch alle auf einmal am anfang.

ich habe noch vergessen zu erwähnen, dass ich den gyroscope sensor zur steuerung des raumschiffes verwende. könnte es damit zusammenhängen?
 
nope.. der Gyro zieht nicht die Leistung, das ist vollkommen ausgeschlossen.

Auf was ist denn deine Framerate eingestellt?

Baue die Logik mit den Bonus-Punkten um, zwei Threads sind hier definitiv nicht notwendig. Nimm die aktuelle Zeit rechne ein paar Sekunden drauf und dann prüfst du bei jedem Schleifendurchlauf, ob die Zeit abgelaufen ist. Damit bist du auf der sicheren Seite - weiß aber nicht genau ob das letztendlich den Fehler verursacht...

Ansonsten ist die Aussage, dass du "anfangs alles lädst" hier nicht wirklich sinnvoll. Wenn die anstehenden Berechnungen die GPU plätten, dann tuen sie das - ob vorher geladen oder nicht, spielt keine große Rolle (jedenfalls zum Zeitpunkt, wenn das Spiel korrekt gestartet ist)...

Android bietet auch für den Canvas einen OpenGL-Support an. Sprich du änderst im Manifest 2,3 Einträge und schon hast du mehr Leistung (jedenfalls auf manchen Geräten). Welche Geräte ab welcher Android-Version unterstützt werden ist leider nicht immer einfach herauszufinden.

Performance-Einbußen könnten auch durch ineffizientes Casten kommen (kann ja zB durch die Umrechnung von DPI in Pixeln passieren). Oder es wurden grundsätzlich falsche Datentypen verwendet (double statt float).

Es gibt regelrecht unendlich viele Gründe warum ein Spiel nicht so läuft wie es sollte - ohne den Quell-Code ist es ziemlich schwierig einen Fehler zu finden. :)
Vielleicht ist das Spiel aber auch schon hinsichtlich des Umfangs schlicht zu heftig, dann wäre ein Umstieg auf OpenGL unausweichlich. Aus meiner eigenen Erfahrung kann ich dir sagen, dass der Canvas schnell an seine Grenzen kommt - gerade wenn man ein paar Effekte im Hintergund laufen lassen will.
 
ich könnte euch ja den quellcode zeigen, aber welche ausschnitte?

das mit opengl meinte auch ein freund von mir. er hat das spiel getestet und meinte, dass es eigentlich viel flüssiger laufen müsste. kann es sein, dass diese draw()-methode von canvas nicht gerade die schnellste ist und dass ich mit opengl doch einen enormen performmanzsprung mache?
 

Ähnliche Themen

E
Antworten
0
Aufrufe
959
ey6799
E
numanoid
Antworten
4
Aufrufe
1.554
numanoid
numanoid
H
Antworten
24
Aufrufe
4.682
swa00
swa00
Zurück
Oben Unten