So komprimieren Sie die Animation eines Spiels Bild für Bild auf ein Minimum der Festplatte

19

Ich entwickle ein Spiel wie Age of Empire (Gebäude auf der Karte) und für jedes Gebäude habe ich ein Sprite Sheet für dessen Animation. Ich benutze Frame für Frame-Animation, um das Gebäude zu animieren (keine andere Methode ist mir sowieso bekannt). Ich bemerke, dass mein Ressourcenordner aufgrund der Bilder, die ich darin ablege, extrem groß wird.

Wie halten Spiele wie CoC und Age of Empires ihre apk-Größe unter 50 Mg? Vermisse ich hier etwas, wenn es um Spieleentwicklung geht?

Vielen Dank

EDIT: Weitere Informationen zu dem Problem, mit dem ich konfrontiert bin

Ich habe eine Menge Animationen Drawables Objekte. Ich habe diesen Weg gewählt, weil er am schnellsten war und die gewünschten Ergebnisse lieferte. Grundsätzlich ist jedes Gebäude eine Animation, in der sich die XML-Datei auf 8 Zeichen bezieht (8 Bilder = 8 Dateien). Alle von ihnen sind PNG wegen der Transparenz. Da ich über 200 Bilder habe, beträgt die Apk-Größe 120 MB (und ich bin noch nicht mit dem Kopieren der Hälfte der Dateien fertig). Das ist es, worauf es ankommt, es muss einen Weg geben, es zu lösen. Bitte unterstützen Sie einen Mitentwickler

Schlange
quelle
Das Komprimieren von Bildern oder das Trennen von Spielinhalten von der apk könnte das sein, wonach Sie suchen.
János Turánszki
Du meinst Erweiterungsdateien? Das Problem, dass Erweiterungsdateien nicht über die unterschiedlichen Dichteordner verfügen, die gezeichnet werden können. Ist es das, was Spiele tun? Ich mache Bild für Bild Animation (Vollbild). Oder bin ich völlig auf dem falschen Weg
Snake
Für alle Fälle habe ich versucht, Ihnen zu helfen und eine Antwort zu geben, um Platz für Ihre Bilder zu sparen. Ihre Frage ist jedoch verwirrend: Es ist nicht klar, ob Sie Techniken wie "Wie halten Spiele wie CoC und Age of Empires ihre apk-Größe unter 50 Mg?" oder wenn Sie nur prüfen möchten, ob es weniger speicherplatzintensive Animationsarten gibt (wie aus Ihrem Titel hervorgeht). Bitte klären Sie, damit ich meine Antwort löschen kann, wenn dies der Fall ist, und Sie genauere Antworten erhalten können.
MAnd
@ Und ich habe meine Antwort bearbeitet, um das Problem weiter zu reflektieren
Snake
2
Für Age of Empires ist es wahrscheinlich eine Kombination aus niedriger Auflösung (IIRC wurde für 640 x 480 entwickelt) und indizierten Bildern (nicht volles RGB).
user253751

Antworten:

24

Aus Ihrer Frage geht nicht hervor, ob Sie wirklich Techniken kennen möchten, mit denen Spiele Speicherplatz sparen können, selbst wenn große Mengen an umfangreichen Bild- / Ressourcendateien vorhanden sind (das ist der Kern der Frage), oder ob Sie nur wissen möchten, ob Es gibt weniger Möglichkeiten, Animationen für Ihre Gebäude zu erstellen, da weniger Speicherplatz benötigt wird (dies wird durch den Titel Ihrer Frage impliziert).

Also, ich werde diese Antwort hier einfügen und versuchen, Ihnen in Bezug auf Platzersparnis zu helfen, wenn Sie viele Bilder haben. Wenn Sie nur Informationen zu Animationstechniken benötigen, mit denen Sie möglicherweise Speicherplatz sparen können, teilen Sie mir dies bitte mit, damit ich die Antwort löschen kann.


In einer ähnlichen Situation gab es jedoch zwei Lösungen, die ich gesehen (und einmal verwendet) habe, um Speicherplatz auf der Festplatte zu sparen:

1) um einzelne Bilder innerhalb eines Bildes zu verketten. Manchmal kann es hilfreich sein. Anstatt also 4 separate Dateien für jedes der folgenden farbigen Quadrate zu speichern, speichere ich alle nebeneinander im selben Bild (und teile sie nur über den Spielcode auf):

Bildbeschreibung hier eingeben

In diesem Beispiel beträgt das Speichern in 4 verschiedenen PNG-Dateien 1255 Bytes, während die einzelne Datei mit allen verketteten 451 Bytes beträgt. Wie viel es helfen kann, hängt natürlich von Fall zu Fall ab, und Sie sollten testen, ob dies je nach Ihren Bildern hilfreich sein kann.

2) um den Ressourcenordner zu komprimieren. Dies kann oft sehr hilfreich sein, um Speicherplatz zu sparen. Wenn das Spiel ausgeführt wird, können Sie das gewünschte Bild entweder dekomprimieren oder aus der komprimierten Datei ziehen - abhängig vom verwendeten Komprimierungsformat. Sehen Sie sich die Antwort der Vergangenheit an, die zu einem Wiki dieser Website wurde: /gamedev//a/37649/72423

Beachten Sie jedoch auch, dass jede Art der Komprimierung je nach verwendetem Bilddateityp mehr oder weniger vorteilhaft sein kann : Vermeiden Sie die doppelte Komprimierung von Ressourcen

Weitere Informationen zur Komprimierung: Stand der Technik bei der Bildkomprimierung?


Schließlich könnten Sie sich auch überlegen, welche Bildtypen für die jeweilige Situation verwendet werden sollen: Welches Bildformat ist speichereffizienter: PNG, JPEG oder GIF?

MAnd
quelle
Danke für die Information. Es ist seltsam, dass Sie die Dateigröße halbieren konnten, indem Sie Dinge in eine Datei packten. Ich dachte am Ende des Tages, es wird die gleiche Pixelanzahl und der gleiche Speicherplatz verwendet. Ich habe meine Frage zur besseren Beantwortung bearbeitet
Snake
@Snake Also, nach der Bearbeitung, die Sie vorgenommen haben, denke ich, dass meine Antwort in der Tat hilfreich sein kann. Das Verketten von Bildern und das Komprimieren können die Größe Ihres Ordners erheblich verringern. Beide Techniken werden regelmäßig in einigen Arten von Spielen verwendet. Bei der Verkettung ist das immer ein überraschender Trick. Probieren Sie es aus: Stellen Sie die Bilder aus einer Sequenz Ihrer Animation nebeneinander und vergleichen Sie die endgültige Größe mit der Summe der einzelnen Bilder. Dann können Sie sehen, ob das in Ihrem Fall hilft. Bei PNGs ist die Komprimierung in der Regel weniger effektiv, es lohnt sich jedoch, die Größe des endgültigen Ordners zu
verringern
@Snake eine Beobachtung, aber: Verketten ist manchmal nicht wert oder erhöht sogar die endgültige Größe ein kleines bisschen. Oft kann es jedoch eine wünschenswerte Reduzierung liefern. Es hängt alles von Ihren Bildern ab
MAnd
Ich erinnere mich, dass ich beide Techniken ausprobiert habe und die Reduktion weniger als 10% betrug. Ich weiß definitiv, dass die Komprimierung bei PNG keine Rolle spielt, aber ich werde die Verkettung versuchen. Das ist der Grund, warum ich gefragt habe, wie andere Spiele das machen, weil sie offensichtlich viel mehr Grafiken haben als meine
Snake
Sie sollten nicht in der Lage sein, einen Ordner voller Bilder zu komprimieren. Die Bilder sollten bereits komprimiert sein und nicht viele wiederholbare Sequenzen aufweisen. In diesem Fall wäre diese zusätzliche Komprimierungsebene Teil des
Bildcodecs
9

Ich würde vorschlagen, dass Sie TexturePacker versuchen

  • Sie können einfach alle Ihre Bilder ziehen und ablegen, um sie zu packen
  • Sie können eine andere Komprimierung anwenden - z. B. indizierte PNGs verwenden, die deutlich weniger Speicherplatz verbrauchen - bis zu 70% weniger als eine Standard-PNG-Datei
  • Sie können Dateidatendateien erstellen, die den Namen und die Position jedes Ihrer Gebäude enthalten
  • Die kostenlose Version könnte bereits ausreichen, um die Sprite-Blätter für Sie zu erstellen

Verwenden Sie ein Spieleentwicklungs-Framework wie AndEngine, Cocos2d-x oder LibGdx? => Keine

Müssen alle Bilder gleichzeitig geladen werden? Es hört sich so an, als würden Sie auf den Zielgeräten auf massive RAM-Probleme stoßen.


Update: Snake hat mir ein paar Bilder geschickt. Wie versprochen, werden sie hier nicht veröffentlicht. Deshalb habe ich selbst einige Kunstwerke geschaffen, um zu demonstrieren, wie der Speicherverbrauch reduziert werden kann.

Im Originalbild bewegte sich nur ein Teil des Bildes. Ich habe einen Vogel auf ein Haus gesetzt, um dies zu demonstrieren:

Bildbeschreibung hier eingeben

Grundsätzlich ist das Packen der gesamten Animation auf ein Blatt eine große Verschwendung von Speicher. Sie sollten statische und bewegliche Teile aufteilen:

Statisch:

Bildbeschreibung hier eingeben

Anim01:

Bildbeschreibung hier eingeben

Anim02:

Bildbeschreibung hier eingeben

Behalten Sie die ursprüngliche Position des Vogels in den Bildern . Deshalb gibt es so mich leeren Raum oben. Sie benötigen dies zum Ausrichten der Animation.

Ziehen Sie nun die Bilder auf TexturePacker und wählen Sie die folgenden Parameter aus

  • Datenformat: JSON-Hash (oder XML, wenn Sie das bevorzugen)
  • TrimMode: Trim (erzeugt Rechtecke)
  • Pixelformat: INDEXED 8bit - zum Erstellen von 8-Bit-PNGs (ca. 70% weniger Speicher)
  • Drehung zulassen: false
  • Geben Sie einen Dateinamen für die Daten ein

TexturePacker packt die Bilder

Das Ergebnis ist, dass Sie jetzt 2 Dateien erhalten: Das Sprite-Sheet und eine JSON-Beschreibungsdatei.

"house_anim_01.png":
{
    "frame": {"x":351,"y":246,"w":110,"h":79},
    "rotated": false,
    "trimmed": true,
    "spriteSourceSize": {"x":67,"y":8,"w":110,"h":79},
    "sourceSize": {"w":400,"h":400},
    "pivot": {"x":0.5,"y":0.5}
},

Die wichtigen Teile sind Frame und SpriteSourceSize .

Der Rahmen gibt Ihnen die Position des ursprünglichen Sprites im Sprite-Sheet an.

spriteSourceSize gibt den Versatz für das Zeichnen des Bildes an - die Teile des Bildes, die aufgrund des Zuschneidens ausgelassen werden:

Eine einfache Pseudo-Code-Zeichenroutine sieht folgendermaßen aus:

drawImage(spritename, posX, posX)
{
    data    = sheetData[spritename]
    offsetX = data.spriteSourceSize.x
    offsetY = data.spriteSourceSize.y
    frameX  = data.frame.x
    frameY  = data.frame.y
    width   = data.frame.w
    height  = data.frame.h
    screen.draw(sheetImage, posX+offsetX, posY+offsetY, width, height)
}

Möglicherweise müssen Sie die Versatzberechnung abhängig vom Drehpunkt / Ursprung in Ihrem Grafiksystem anpassen. Die obige Routine setzt ein Koordinatensystem voraus, dessen Ursprung oben links liegt.

Dann zeichnen Sie das Haus einfach in 2 Durchgängen:

draw("background", 100, 100);
draw("anim_01", 100, 100);

Sie müssen sich nicht um die Offsets kümmern, da die Bilder bereits ausgerichtet sind.

Andreas Löw
quelle
+1 für die Beobachtung der RAM-Nutzung, die andere Leute ignorieren
Dan Hulme
@ Andreas Ich werde das überprüfen. Vielen Dank. Lach mich nicht aus, aber ich benutze keinen Motor. Es wird meistens mit Animation und Drawables gemacht und es funktioniert wie ein Zauber. Ich lade nicht alle Bilder in den Speicher, sonst stürzt es ab. Es werden nur die Bilder geladen, die zur Anzeige im Moment benötigt werden. Glauben Sie, dass der obige Vorschlag mit Standard-Android-SDK funktioniert?
Snake
1
Ja, es wird. TexturePacker verfügt über zwei Modi zum Trimmen von Sprites: Rechtecke und Polygone. Wenn Sie isometrische Bilder verwenden, erhalten Sie möglicherweise einen großen Vorteil von Polygonnetzen in Bezug auf das Packen. Die Frage ist, ob Sie strukturierte Dreiecke oder Rechtecke mit einer Maske zeichnen können. Ist dies nicht der Fall, können Sie die Rechtecke weiterhin verwenden. Sie können mir einige Ihrer Bilder senden, wenn Sie Dropbox verwenden möchten und einen Link an -> support at codeandweb senden. com. Ich werde sie nicht teilen - nur interessiert, was wir tun können, um die Verpackung zu verbessern.
Andreas Löw
@ AndreasLöw Es tut mir so leid, ich habe keine Benachrichtigung über Ihren Kommentar erhalten. Ich habe es gerade gesehen. Ich werde die Hilfe sehr schätzen. Ich werde dir etwas schicken und vielleicht kannst du Licht ins Dunkel bringen, was ich sollte. ..kinda mit etwas stecken bleiben Ich habe wenig Erfahrung in und vielleicht können Sie Licht ausstrahlen. Ich melde mich bald
Snake
7

Hier sind einige Zeiger, die Sie verwenden können

  1. Stellen Sie sicher, dass nicht alle Hintergrund- und nicht transparenten Bilder im PNG-Format vorliegen
  2. Versuchen Sie, alle Animationen loopfähig zu machen, dh wenn die Animation 1,2,3,4,5,6 ist, versuchen Sie, sie wie 1,2,3,4,3,2,1 zu machen, wobei diese Zahlen die Bildnummer der Animation sind. es hilft sehr
  3. Wenn viele Bilder gleich sind und sich nur die Farben unterscheiden (im Allgemeinen UI-Schaltflächen, m Partikelanimationen, Spielmünzen), versuchen Sie, ein weißes Bild aufzunehmen und seine Farbe dynamisch zu ändern
  4. Versuchen Sie, Ihre .apk-Datei nur mit den äußerst wichtigen Bildern zu erstellen, und laden Sie dann alles von einem Server und behalten Sie den Telefonspeicher bei

Ich hoffe, diese Hinweise helfen

PS: Ich gebe nur eine verallgemeinerte Vorstellung, da mir Ihr genauer Spielinhalt und Ihre Entschuldigung nicht bekannt sind, wenn diese Hinweise nicht nützlich sind

Kumar Saurabh
quelle
Sie können auch: 1) alle Ihre Bilder komprimieren 2) Kacheln so oft wie möglich verwenden 3) Bilder zu einem größeren Bild zusammenfassen und als UV-Map für die Texturierung verwenden
Anthony Raimondo,
Das sind tolle Vorschläge. Vielen Dank. Ich denke, der wichtigste Punkt ist 4. Wenn dies der Fall ist, wie lege ich sie dann in die verschiedenen Zeichenordner und verweise auf sie wie R.drawable.image1? Das ist, wo ich verwirrt bin
Schlange
4

Viele Spiele behalten ihre grafischen Ressourcen nicht in der .apk-Datei. Sie enthalten nur die "Grundlagen" wie UI-Grafiken und den Spielcode und laden den Rest der Assets herunter, sobald das Spiel installiert ist. Dies gilt insbesondere für Spiele, die abhängig von der Auflösung Ihres Displays unterschiedliche Grafikressourcen verwenden, um zu verhindern, dass die APK-Datei sowohl Assets mit niedriger als auch mit hoher Auflösung enthalten muss.

Sie sollten sich sowohl die Optimierungsoptionen der anderen Antwortenden als auch die Frage ansehen, ob Sie die Grafiken Ihres Spiels letztendlich getrennt von der .apk-Datei selbst bereitstellen müssen.

Sandalfoot
quelle
Ich habe keine Probleme beim Abrufen der Grafiken vom Server (oder sogar von Erweiterungsdateien), aber wie lege ich sie in einen zeichnungsfähigen Ordner, damit ich sie mit R.drawable.x referenzieren kann? Da die meisten meiner (vielen) XML-Dateien auf sie mit R verweisen .drawable
Snake
AFAIK, das kannst du nicht. Eine Problemumgehung besteht darin, eine Hash-Tabelle mit Ressourcendateinamen zu erstellen, die mit Ressourcen-IDs verknüpft sind, und die Dateien anhand dieser IDs mit AssetManager abzurufen. Möglicherweise müssen Sie Ihre XML-Dateien jedoch überarbeiten, wenn Sie diesen Weg gehen.
Sandalfoot
4

Ich bin auf diese Site gekommen, um eine ähnliche Frage zu finden, und es gibt in der Tat einige gute Ressourcen, die sowohl in den Antworten auf Ihre Frage als auch in anderen Fragen aufgeführt sind.

Sie sollten sich wahrscheinlich 2D-Animationen ansehen : Animierte 3D-Modelle oder Sprites mit Animationsrahmen? für einige Debatten über verschiedene Arten von Animationen. Es hat mir geholfen, mein Spiel zu optimieren. Außerdem teilen Sie uns nicht mit, welche API Sie verwenden oder welche Engine Sie verwenden. Das alleine kann schon einen Unterschied machen: Android Frame für Frame PNG Animation

Bedenken Sie außerdem, dass es bei der Komprimierung wichtige Unterschiede zwischen den Komprimierungsmethoden geben kann. Insbesondere gibt es einige Unterschiede zwischen den Komprimierungsarten und es gibt einige spezielle Debatten darüber, welche Route für Mobilgeräte am besten geeignet ist. Insbesondere wenn Sie berücksichtigen, dass für mobile Geräte auch die RAM-Auslastung und die CPU-Verschwendung beim Laden von größter Bedeutung sind. Siehe: http://www.gamasutra.com/blogs/AlexandruVoica/20130419/190833/Why_efficiency_is_key_in_texture_compression_standards_for_mobile_graphics.php?print=1

Bennton
quelle
Danke Bennton, ich bin eigentlich neu in der Spieleentwicklung. Ich habe viele Apps entwickelt, die auf Tools / Produktivität basieren. Aber keine mit Spielen. Also mache ich mein erstes Spiel und benutze keine Engine. Ich benutze nur AnimationDrawables und die Dinge funktionieren großartig. Es ist nur die Größe der apk wird außer
Snake
Besonders interessant ist Bennton, der letzte von Ihnen vorgeschlagene Link. Vielen Dank für das Teilen! Sehen Sie sich unbedingt die letzte Antwort aus meiner Antwort an, in der auch das Problem der unterschiedlichen Komprimierung für verschiedene Dateitypen angesprochen wird. Tatsächlich scheint es Komprimierungstypen zu geben, die besser mit bereits komprimierten Bildtypen wie PNG oder besser mit nicht komprimierten Bildtypen funktionieren. Das Experimentieren für jeden Fall ist immer der beste Weg, um zu überprüfen, was für jede Situation am besten funktioniert.
MAnd