Ich erstelle ein Spiel in jQuery, in dem ich ungefähr 10000 32x32-Kacheln verwende. Bisher habe ich sie alle einzeln verwendet (kein Sprite Sheet). Eine durchschnittliche Karte verwendet ungefähr 2000 Kacheln (manchmal wiederverwendete PNGs, aber alle separaten Divs) und die Leistung reicht von stabil (Chrome) bis etwas verzögert (Firefox). Jede dieser Divs wird absolut mit CSS positioniert. Sie müssen nicht bei jedem Tick aktualisiert werden, nur wenn eine neue Karte geladen wird.
Wäre es für die Leistung besser, Spritesheet-Methoden für die Divs mit CSS-Hintergrundpositionierung zu verwenden, wie dies bei gameQuery der Fall ist?
Danke im Voraus!
Antworten:
Mein Vorschlag
Zu viele kleine PNGs verursachen einen hohen Netzwerk-Overhead (aufgrund der Größe der HTTP-Anforderungen, aber auch des PNG-Headers und wahrscheinlich, was noch wichtiger ist, der Unfähigkeit, eine effiziente Komprimierung durchzuführen). Andererseits hat eine sehr große PNG den Nachteil, dass das Laden einige Zeit in Anspruch nimmt und dauerhaft im Speicher (40 Megabyte für 10.000 Kacheln) in einem zusammenhängenden Speicherblock verbleiben muss.
Ich empfehle den Mittelweg: mehrere PNGs von angemessener Größe, zum Beispiel 1024 Kacheln der Größe 32 × 32 . Vielleicht nach Themen gruppiert (zum Beispiel eine PNG mit Waldkacheln, eine mit Bergkacheln, eine andere mit Stadtkacheln - ich kenne das Thema Ihres Spiels nicht, aber Sie haben die Idee).
Hinweis zur Cache-Effizienz
Wegen der Effizienz des Speicherzugriffs sollten Sie Ihre Spritesheets niemals zu breit machen. Das Ausschneiden von Kacheln aus einem 128 × 8192-Bild ist immer schneller als das Ausschneiden aus einem 8192 × 128-Bild.
Stellen Sie sich vor, Sie möchten die erste Kachel in einem 8192 × 128-Bild aufteilen. Der Einfachheit halber wird angenommen, dass 1 Pixel 1 Byte ist. Die ersten beiden Pixelzeilen sind so angeordnet (Zellen enthalten ihre Bytenummer im Speicher):
Also, um das blitten ersten Zeile des ersten Titels, wird der Browser - Engine abrufen Bytes
0
zu31
. Um die blitten zweite Zeile , wird es abrufen Bytes8192
auf8223
, und so weiter , bis der 32. Zeile , in Bytes253952
zu253983
werden abgerufen.Die Gesamtzahl der verarbeiteten Bytes beträgt 32 × 32. Der gesamte Speicherbereich beträgt jedoch mehr als 253984 Byte. Auf einer modernen CPU bedeutet dies 32 oder 33 Cachestände . Im Gegensatz dazu würde der Speicherbereich bei einem Bild von 128 × 8192 nur 4000 Byte betragen, was bedeutet, dass nicht mehr als zwei Cachestände vorhanden sind.
Da die heutigen CPUs sehr schnell sind, sind Cache-Stalls sehr teuer und hängen Berechnungen. Die Verwendung eines 128 × 8192-Bilds anstelle eines 8192 × 128-Bilds ist also theoretisch potenziell mindestens achtmal so schnell. In der Praxis hängt dies davon ab, wie das Blitting implementiert wird: Es ist möglich, dass die zugrunde liegende Engine selbst Bilder in Kacheln aufteilt, um das Problem zu verringern.
Das ist nicht leicht zu erklären und ich habe nicht damit gerechnet, viel näher darauf einzugehen. Ich hoffe es macht Sinn!
quelle
Ein riesiges Spritesheet wird Ihnen (wahrscheinlich) eine bessere Leistung bringen, einfach weil eine der größten Ursachen für Verzögerungen die Hin- und Rückfahrt von der Browseranforderung zum Server zum Browser ist. 10.000 HTTP-Aufrufe werden viel, viel länger dauern als 1 HTTP-Aufruf, der eine Datei zurückgibt, die 10.000 größer ist.
Abhängig von der Struktur des Spiels und dem von Ihnen erstellten HTML-Code gibt es möglicherweise andere Möglichkeiten, um die Verzögerung zu verringern.
quelle