SpriteKit, wo Texturatlanten für Tausende von Sprites geladen werden

7

In meinem Spiel habe ich Tausende von "Kacheln" -Knoten, die eine Spielkarte bilden (denke simcity), ich frage mich, welcher Frame-Rate / Speicher-effiziente Weg zum Texturieren und Animieren jedes Knotens wäre? Es gibt eine Handvoll einzigartiger Kachel- "Typen", die jeweils ihre eigenen Texturatlas / Animationen haben. Daher ist es wichtig, dass die Texturen wiederverwendet werden, wenn es möglich ist.

Alle meine tile -Knoten sind Kinder eines einzelnen map -Knotens, sollte der Kartenknoten die Erkennung eines Kacheltyps und das Laden des erforderlichen atlas & amp; Animationen (z. B. durch Laden von Textur- und Atlasnamen von einem Plist?)

Alternativ ist jeder Kacheltyp eine bestimmte Unterklasse. Wäre es besser für jede SKSpriteNode-Kachel, ihre eigene Sprite-Atlas-Last z.B. [tileInstance texturise]; (Wie geht Sprite Kit damit um? Würde diese Methode dazu führen, dass für jede Instanz eines bestimmten Kacheltyps derselbe Texturatlas in den Speicher geladen wird?)

Ich habe die Dokumente für eine tiefere Erklärung von Atlanten und Texturwiederholung durchforstet, aber ich weiß nicht, wie das typische Verfahren für ein Szenario wie dieses ist. Jede Hilfe wäre dankbar, danke.

    
Cal S 14.10.2013, 05:11
quelle

1 Antwort

21

Speicher zuerst: Es wird keinen bemerkbaren Unterschied geben. Sie müssen die Texturen der Fliese laden, Texturen machen mindestens 99% des Speichers der Karte + Fliese aus und das ist das.

Texturwiederverwendung: Texturen werden automatisch wiederverwendet / zwischengespeichert. Zwei Sprites, die die gleiche Textur verwenden, verweisen auf die gleiche Textur und nicht auf eine eigene Kopie der Textur.

Framerate / Batching: Hier geht es um richtiges Batching. Sprite Kit nähert Batch-Children eines Knotens an, indem sie sie in der Reihenfolge rendern, in der sie dem Child-Array hinzugefügt werden. Solange der nächste untergeordnete Knoten die gleiche Textur wie die vorherige verwendet, werden alle zu einem Zeichenaufruf zusammengefasst. Möglicherweise ist das Schlimmste, was Sie tun könnten, ein Sprite, ein Label, ein Sprite, ein Label und so weiter hinzuzufügen. Sie möchten so viele Sprites hinzufügen, dass Sie die gleiche Textur in fortlaufender Reihenfolge verwenden.

Atlas Usage : Hier können Sie am meisten gewinnen. Üblicherweise versuchen Entwickler ihre Atlanten zu kategorisieren, was der falsche Weg ist. Anstatt einen Atlas pro Kachel (und seine Animationen) zu erstellen, sollten Sie so wenig Texturatlanten wie möglich erstellen, wobei jeder so viele Kacheln wie möglich enthält. Auf allen iOS 7 Geräten kann ein Texturatlas 2048x2048 sein und mit Ausnahme von iPhone 4 und iPad 1 können alle anderen Geräte Texturen mit bis zu 4096x4096 Pixeln verwenden.

Es gibt Ausnahmen von dieser Regel, sagen wir, wenn Sie so viele Texturen haben, dass Sie sie nicht alle gleichzeitig auf allen Geräten in den Speicher laden können. In diesem Fall sollten Sie nach bestem Wissen einen guten Kompromiss zwischen Speicherverbrauch und Batch-Effizienz finden. Zum Beispiel könnte eine Lösung darin bestehen, ein oder zwei Texturatlanten für jede einzelne Szene oder vielmehr "Szenerie" zu erstellen, auch wenn das bedeutet, dass einige Kacheln in anderen Texturatlanten für eine andere Szene dupliziert werden. Wenn Sie Fliesen haben, die fast immer in irgendeiner Landschaft erscheinen, würde es Sinn machen, diese in einen "geteilten" Atlas zu legen.

Wie für die Unterklassen -Kacheln bin ich ein starker Befürworter, um die Unterklassenbildung von Knotenklassen zu vermeiden. Vor allem, wenn der Hauptgrund für die Unterklasse darin besteht, nur die Textur zu ändern, die sie verwenden / animieren. Ein Sprite ist bereits ein Container mit einer Textur, also kannst du auch die Sprite-Textur ändern und von außen animieren.

Um einem Knoten Daten oder zusätzlichen Code hinzuzufügen, können Sie die Eigenschaft userData durchsehen, indem Sie Ihr eigenes NSMutableDictionary erstellen und ein beliebiges Objekt hinzufügen, das Sie benötigen. Ein typischer komponentenbasierter Ansatz würde so aussehen:

%Vor%

Dieses Controller-Objekt führt dann jeden benutzerdefinierten Code aus, der für Ihre Kacheln benötigt wird. Es könnte die Kachel und was auch immer animieren. Das einzige wichtige Bit ist, dass der Verweis auf den besitzenden Knoten (hier: Sprite) eine schwache Referenz ist:

%Vor%

Weil das Sprite das Wörterbuch behält. Das Wörterbuch behält den Controller bei. Wenn der Controller das Sprite beibehalten würde, könnte das Sprite nicht freigegeben werden, da es immer noch einen Verweis darauf geben würde - daher behält es weiterhin das Wörterbuch bei, das den Controller beibehält, der das Sprite behält.

Die Vorteile eines komponentenbasierten Ansatzes (der auch von Kobold Kit favorisiert und implementiert wird):

  • Wenn es richtig konstruiert ist, arbeitet es mit einem oder mehreren Knoten. Wenn was, wenn Sie eines Tages eine Beschriftung, einen Effekt, eine Knoten-Kachel gestalten möchten?
  • Sie brauchen keine Unterklasse für jede Kachel. Einige Kacheln können einfache statische Sprites sein. Also benutze einfach statische SKSpriteNode für diese.
  • Sie können einzelne Aspekte nach Bedarf starten / stoppen oder hinzufügen / entfernen. Selbst auf Kacheln hattest du ursprünglich nicht erwartet, dass du einen bestimmten Aspekt hast oder brauchst.
  • Komponenten ermöglichen es Ihnen, ein Repertoire an Funktionen zu erstellen, die Sie oft und möglicherweise sogar in anderen Projekten benötigen werden.
  • Komponenten sorgen für eine bessere Architektur. Ein klassischer OOP-Designfehler ist es, Spieler- und Enemy-Klassen zu haben, dann erkennen, dass beide in der Lage sein müssen, Pfeile abzuschießen und Rüstungen auszurüsten. Sie verschieben den Code in die root-GameObject-Klasse und machen den Code für alle Unterklassen verfügbar. Mit Komponenten haben Sie einfach eine Ausrüstung und eine Shooting-Komponente zu den Objekten hinzufügen, die es brauchen.
  • Der große Vorteil von komponentenbasiertem Design besteht darin, dass Sie einzelne Aspekte getrennt von anderen Dingen entwickeln, sodass sie bei Bedarf wiederverwendet und hinzugefügt werden können. Sie werden fast natürlich besseren Code schreiben, weil Sie Dinge mit einer anderen Denkweise angehen.
  • Und nach meiner eigenen Erfahrung, wenn Sie ein Spiel in Komponenten modularisieren, erhalten Sie viel weniger Fehler und sie sind einfacher zu lösen, weil Sie den Code anderer Komponenten nicht ansehen oder berücksichtigen müssen - außer wenn sie von einer Komponente verwendet werden Wenn dann eine Komponente eine andere auslöst, haben Sie eine klare Grenze, dh ist der übergebene Wert immer noch korrekt, wenn die andere Komponente übernimmt?Wenn nicht, muss der Fehler in der ersten Komponente sein.

Dies ist eine gute Einführung in das komponentenbasierte Design . Der Hybrid-Ansatz ist sicherlich der Weg zu gehen. Hier sind mehr Ressourcen zum komponentenbasierten Design aber ich rate dringend davon ab, vom Pfad abzukommen und Ein Blick in FRP als "akzeptierter Autor der Antwort" legt nahe - FRP ist ein interessantes Konzept, hat aber (noch) keine reale Anwendung in der Spieleentwicklung.

    
LearnCocos2D 14.10.2013, 08:37
quelle

Tags und Links