Objektpools helfen Ihnen, Verzögerungen bei ressourcenintensiven Spielen zu reduzieren

Schützen und Spiele, die Partikelsysteme verwenden, müssen viele Objekte gleichzeitig erstellen, bearbeiten und entfernen - möglicherweise sogar Hunderte pro Frame. Dies kann dazu führen, dass das Spiel verzögert oder sogar eingefroren wird. In diesem Tutorial sehen wir uns an, wie Objektpools kann bei diesem Problem helfen, indem wir die Objekte wiederverwenden können, anstatt sie von Grund auf neu zu erstellen.

Hinweis: Obwohl dieses Tutorial mit Java geschrieben wurde, sollten Sie in der Lage sein, in fast jeder Spieleentwicklungsumgebung dieselben Techniken und Konzepte anzuwenden.


Einführung

Bei Schützen und Partikelsystemen kommt es häufig vor, dass viele Objekte in schneller Folge erstellt und gelöscht werden. Das Erstellen und Löschen der benötigten Objekte kann eine teure Operation sein. Wenn viele dieser Vorgänge schnell durchgeführt werden, kann das Spiel verzögern oder einfrieren.

Der Grund ist, dass ein Hintergrundprogramm die Müllsammler erfordert Systemressourcen, um den verwendeten Speicher aufzuräumen. Durch dieses Aufräumen kann das System verzögern.

Um dies zu verhindern, können Sie einen Objektpool verwenden, um alte Objekte wiederzuverwenden, anstatt sie zu löschen.


Was ist Müllsammlung??

Um zu verstehen, warum ein Objektpool benötigt wird, müssen wir zuerst verstehen, wie die Garbage Collection funktioniert.

Garbage Collection ist der Prozess der automatischen Ressourcenverwaltung. Es ist dafür verantwortlich, Speicherplatz für die Wiederverwendung freizugeben, wenn es nicht mehr benötigt wird.

Schauen Sie sich das folgende Beispiel eines einfachen an zum Schleife:

 für (int i = 1; i < 10; i++)  System.out.println(i); 

Wenn ein Programm diese Schleife ausführt, wird eine Variable erstellt ich indem Sie genügend Speicherplatz für die Daten der Variablen zuweisen (in diesem Fall genügend Speicherplatz für eine Ganzzahl). Sobald die Schleife beendet ist, wird die Variable angezeigt ich wird nicht mehr benötigt; Das Programm erkennt dies schließlich und kann den Speicher für andere Zwecke freigeben.

Meistens erfolgt die Müllsammlung automatisch und ohne Vorankündigung. Wenn jedoch viel Speicher auf einmal freigegeben werden muss, kann die Garbage Collection das Programm zwingen, wertvolle Systemressourcen zu verwenden, um den benötigten Speicher freizugeben. Dies kann dazu führen, dass das Programm zeitweilig verzögert oder einfriert, da dies Zeit benötigt.

Das System kann auch verzögern, wenn viel Speicher auf einmal benötigt wird, um neue Objekte zu erstellen. Dies liegt daran, dass die Zuweisung von Speicher genauso ressourcenintensiv sein kann wie die Freigabe von Speicher.

Aus diesem Grund ist es wichtig, die Speicherbereinigung so zu verwalten, dass Ihr Programm nicht beeinträchtigt wird.


Was ist ein Objektpool??

Ein Objektpool ist eine Datenstruktur, die alte Objekte wiederverwendet, um nicht ständig neue Objekte zu erstellen oder zu löschen. Anstatt einem Objekt neuen Speicherplatz zuzuweisen und ihn dann freizugeben, sobald wir damit fertig sind, verwenden wir das Objekt immer wieder, indem wir seine Werte ändern. Auf diese Weise muss der Speicher nicht freigegeben werden, so dass die Speicherbereinigung vermieden wird.

Das Zusammenlegen von Ressourcen kann in Situationen, in denen die Kosten für die Initialisierung einer Klasseninstanz hoch sind, die Instanziierungsrate einer Klasse hoch ist und die Anzahl der jeweils verwendeten Instanzen niedrig ist, eine erhebliche Leistungssteigerung bieten.

Stellen Sie sich ein It wie ein Kartenspiel vor, bei dem das Deck Speicher darstellt. Jedes Mal, wenn Sie eine neue Karte benötigen (d. H. Sie benötigen ein neues Objekt), ziehen Sie eine Karte aus dem Stapel und verwenden Sie sie. Wenn Sie mit der Karte fertig sind, werfen Sie sie in einen kleinen Mülleimer.

Möglicherweise haben Sie keine Karten mehr und brauchen ein neues Deck, oder der Müll kann voll werden und muss herausgenommen werden (d. H. Müllsammlung). In beiden Fällen müssen Sie das, was Sie gerade tun, stoppen, um entweder ein neues Deck zu erhalten oder den Müll zu entfernen.

In einem Objektpool ist jede Karte im Deck leer. Wenn Sie eine Karte benötigen, schreiben Sie die grundlegenden Informationen darauf und verwenden Sie sie. Wenn Sie mit der Karte fertig sind, löschen Sie die Informationen und legen Sie sie wieder in das Deck ein. Auf diese Weise werden keine neuen Karten benötigt und Sie müssen niemals eine Karte in den Papierkorb werfen. Es ist der Weg des Programmierers zum Recycling!


Einen Objektpool implementieren

Das Implementieren eines Objektpools ist nicht allzu schwierig, aber da ein Objekt dazu benötigt wird, werde ich Ihnen auch zeigen, wie das Objekt implementiert wird, das der Objektpool enthalten wird. Da ein Objektpool am besten für Objekte geeignet ist, die schnell erstellt und gelöscht werden müssen, erscheint ein Partikelsystem als die ideale Wahl. Es ist ein Special für zwei!

Wir beginnen zuerst mit der Implementierung von Partikel Klasse. Der folgende Code ist in Java geschrieben. Dieselben Techniken können jedoch für die meisten anderen Programmiersprachen verwendet werden. Ich werde nach jedem Code-Snippet einen Kommentar abgeben.

 öffentliche Klasse Particle private int framesLeft; private int posX; privat int posY; private int xVelocity; private int y Geschwindigkeit; / ** * Konstruktor * / public Particle () framesLeft = 0; posX = 0; posY = 0; xVelocity = 0; yVelocity = 0;  / ** * Alle Variablen vor der Verwendung initialisieren. posX = pPosX; posY = pPosY; xVelocity = pXVelocity; yVelocity = pYVelocity;  / ** * Das Partikel animieren * / public boolean animate () if (isAlive ()) posX + = xVelocity; posY + = y Geschwindigkeit; framesLeft--; // Zeichne das Objekt auf den Bildschirm. Return false;  return true;  / ** * Stellen Sie fest, ob ein Partikel lebt (oder verwendet wird) * / public boolean isAlive () return framesLeft> 0; 

Wie Sie sehen, ist ein Partikel ein sehr einfaches Objekt. Es enthält einige Variablen, um zu verfolgen, wo es sich auf dem Bildschirm befindet (posX und Sträußchen), wie schnell es geht (xVelocity und y Geschwindigkeit) und wie viele Frames gezeichnet werden sollen (framesLeft). Ein Teilchen ist "lebendig", wenn noch Frames zum Zeichnen vorhanden sind, andernfalls "tot".

Bei jedem Bild das animieren Die Funktion wird aufgerufen, um die Position des Partikels zu aktualisieren und auf den Bildschirm zu zeichnen. Es kehrt zurück falsch Wenn das Teilchen noch am Leben ist, gibt es ansonsten wahr zurück, was das Teilchen bedeutet ist gestorben.

Hinweis: Der Code zum Zeichnen des Partikels liegt außerhalb des Rahmens dieses Tutorials.

Als nächstes implementieren wir die ObjectPool Klasse:

 öffentliche Klasse ObjectPool private int size; private Listenteilchen; / ** * Konstruktor * / public ObjectPool (int pSize) Größe = pSize; Partikeln = neue ArrayList (); // Initialisiere das Array mit Partikeln für (int i = 0; i < size; i++)  particles.add(new Particle());   /** * Get the first available particle and assign it the new values */ public void get(int pFramesLeft, int pPosX, int pPosY, int pXVelocity, int pYVelocity)  if (!particles.get(size-1).isAlive())  particles.get(size-1).init(pFramesLeft, pPosX, pPosY, pXVelocity, pYVelocity); particles.add(0, particles.remove(size-1));   /** * Animate the object pool. Any dead particles will be placed at the front of the list to be reused */ public void animate()  for (int i = 0; i < size; i++)  if (particles.get(i).animate())  particles.add(size-1, particles.remove(i));    

Das ObjectPool Klasse ist auch ein relativ einfaches Objekt. Es enthält nur eine Liste von Partikeln und die Größe der Liste. Die Leistungsfähigkeit des Objektpools liegt in seinen zwei Methoden, erhalten und animieren.

Wenn der Objektpool ein neues Objekt zur Verwendung benötigt, prüft er das letzte Element in der Liste und prüft, ob es derzeit aktiv oder tot ist. Wenn es lebendig ist, ist der Pool voll und ein neues Objekt muss erstellt werden. Wenn es tot ist, initialisiert der Pool das letzte Element in der Liste, ruft es vom Ende aus auf und schiebt es wieder an den Anfang der Liste. Auf diese Weise hat der Pool immer Objekte auf der Rückseite und verwendete Objekte auf der Vorderseite.

In dem animieren Methode, wenn die Animationsfunktion des Partikels zurückkehrt wahr, Das Objekt ist zur Wiederverwendung bereit. Der Pool entfernt das Element aus der Liste und schiebt es nach hinten. Durch das Manipulieren der Liste auf diese Weise wird das Erstellen und Zerstören von Objekten im Pool konstant und sehr effizient.

In diesem Beispiel sind die Objekte, die der Objektpool aufnehmen soll, Partikel, für Ihren eigenen Objektpool kann es jedoch beliebig sein. Solange in dem Objekt, das Sie verwenden, dieselben Funktionen vorhanden sind wie in der Partikelklasse, funktioniert es genauso.


Alles zusammenfügen

Ausgestattet mit einem Objektpool ist es an der Zeit, ein Partikelsystem zu erstellen, um einen Wunderkerzeffekt zu erzeugen.

Wir beginnen mit dem Erstellen eines Objektpools, der alle Partikel auf dem Bildschirm enthält.

 ObjectPool-Pool = neuer ObjectPool (100);

Bei jedem Bild erzeugen wir ein neues Teilchen in der Mitte des Bildschirms und weisen ihm eine zufällige Geschwindigkeit zu. Zum Schluss animieren wir den Objektpool.

 Random randomGenerator = new Random (); int velX = randomGenerator.nextInt (5); int velY = randomGenerator.nextInt (5); pool.get (30, 200, 200, velX, velY); pool.animate ();

Fazit

Durch schnelles Erstellen und Löschen von Objekten kann ein Spiel verzögern oder einfrieren. Durch die Verwendung eines Objektpools können Sie sowohl Systemressourcen als auch Benutzerfrust sparen.