Teil 13: Resource Preloading

So, es geht endlich mal wieder weiter mit unserem kleinen Tutorial. Zu dumm, wenn man nebenbei noch eine kleine Diplomarbeit schreiben muß ;)

Also, wir hatten beim letzten Mal festgestellt, daß es sich mitunter negativ auf die Performance auswirken könnte, wenn Grafiken ständig neu geladen und wieder freigegeben werden. Es ist ja auch irgendwie Blödsinn. Wir werden im Spiel nicht solche Unmengen an Grafiken haben, als daß wir nicht gleich alle zu Beginn laden könnten. Ebenso wird es sich mit den Sounds verhalten. Wir werden also ein möglichst allgemeines System schreiben, das uns solche Ressourcen zu Beginn lädt. Allgemein bedeutet, daß wir zunächst einmal eine Resource-Klasse entwerfen müssen, die später unsere Grafiken/Sounds/… aufnehmen wird. Im Moment ist da nur der Dateiname interessant, der zu der Resource gehört, damit diese sich hinterher im Notfall auch mal selbst neuladen kann. So sieht unsere Interface-Klasse für die Ressourcen also aus:

Datei /core/Resource.h:

Der ein oder andere kennt vielleicht den STL Container “map” noch nicht, den ich hier verwende, deshalb möchte ich ganz kurz darauf eingehen, worum es sich dabei handelt. Die map ist ein sogenannter assoziativer Container, das bedeutet, daß sie zwei Werte miteinander verknüpft, eine Zuordnung herstellt. Ein Array funktioniert ähnlich: Hier kann ich mit einem Index auf ein bestimmtes Element zugreifen. Die Einschränkung ist allerdings, daß der Index eine Ziffer sein muß. Wir möchten über einen Alias, z.B. “glider”, eine Resource anfordern, und “glider” lässt sich schlecht als Array-Index verwenden. Deshalb hilft uns die map, eine Zuordnung von string zu IResource* herzustellen.

Wie sollen solche Resourcen nun definiert werden? Ich mache es hier mal ganz einfach: Wir legen eine Textdatei an, in der eine beliebige Anzahl von Alias und Dateiname untereinander stehen. Ein Resourcemanager, den wir gleich noch angehen werden, lädt solche Dateien und die entsprechenden Resourcen. Für unsere bisherigen Grafiken des Gleiters und des Weltraumschrotts wird die Resourcedatei also zunächst so aussehen:

Datei /resource/preload-gfx.txt:

Der ResourceManager muß nun noch wissen, um was für einen Typ Ressource es sich handelt. Das sollten wir beim Laden als Parameter übergeben können. Aufgrund der Tatsache, daß der ResourceManager von überall aus ansprechbar sein sollte (z.B. wird ja der Gleiter auch wieder sein Bitmap irgendwoher holen müssen), wählen wir für die Implementierung wieder das Singleton-Prinzip.

Datei /core/ResourceManager.h:

Die Funktion Preload wird uns also dazu dienen, eine Datei wie oben zu sehen zu laden, und die Resourcen in die map m_mapResources einzupflegen. Die Funktion GetResource gibt eine solche Ressource dann wieder zurück, so daß sie im Programm verwertet werden kann. Interessant ist oben noch die Include-Datei ResourceFactory.h.

Wie schon gesagt, wird es verschiedene Resource-Typen geben, z.B. Grafiken im BMP Format oder Sounds im WAV Format. Also muß entsprechend dem in Preload angegebenen Parameter eResType der richtige Ressourcetyp dynamisch angelegt werden. Darum kümmert sich dann diese Factory-Methode. Das Prinzip ist kein anderes, als wie wir es schon beim GameManager oder EntityManager kennengelernt haben. Zunächst aber mal die Implementierung des ResourceManagers:

Datei /core/ResourceManager.cpp:

Die eben angesprochene Factory sieht vorerst folgendermaßen aus:

Datei /core/ResourceFactory.h:

Datei /core/ResourceFactory.cpp:

Fehlt nun nur noch der erste tatsächliche Ressourcetyp, die Bitmap-Ressource. Die unterscheidet sich zunächst einmal nur durch einen SDL_Surface* als Member von der Basisklasse:

Datei /core/ResourceBMP.h:

Datei /core/ResourceBMP.cpp:

Wie Du Dir sicher denken kannst, werden unsere Klassen also in Zukunft nicht mehr direkt den SDL_Surface* halten, sondern einen CResourceBMP*, den sie vom ResourceManager anfordern.

Die große Frage ist nun noch: Wo werden die Grafiken vorgeladen? Dafür werden wir, oder besser: Du, einen neuen GameState einfügen, GS_Preload. Hier soll zunächst nur die Preload-Methode für die Grafikliste aufgerufen werden, und dann direkt zum nächsten GameState GS_Game gewechselt werden. Das ganze soll Deine Aufgabe bis zum nächsten Tutorial-Teil sein.

Aufgaben

  • Erstelle eine neue GameState-Klasse CGSPreload, in welcher in der Idle-Methode die Liste von Grafiken über den ResourceManager vorgeladen wird und dann zum Spiel-GameState gewechselt wird.
  • Ändere den Start-GameState von GS_Game zu GS_Preload.
  • Sorge dafür, daß Gleiter- und Schrott-Klasse nicht mehr direkt die Grafiken laden, sondern die vom Resource-Manager angeforderten CResourceBMP* verwenden.

Übrigens: Das ganze Ressource-Management-Zeugs ist ein Kapitel für sich, und man könnte das beliebig kompliziert gestalten. Normalerweise gehört da auf jeden Fall noch sowas wie Reference Counting etc. rein. Wir halten es aber erstmal unseren Zwecken entsprechend einfach.

Popularity: 1%


Write a Comment

Take a moment to comment and tell me what you think. Some basic HTML is allowed for formatting.

Reader Comments

Be the first to leave a comment!




FireStats icon Powered by FireStats