1 / 18

Datenstrukturen

Datenstrukturen. Look-Up Tabellen, Zufallszahlen, Listen, Speichermanagement und Dateiverwaltung. Look-Up Tabellen: Probleme bei Spielen. Spielszenen müssen sehr oft pro Sekunden berechnet werden Wenn es zu viele Berechnungen werden fängt das Spiel an zu „ruckeln“

rigg
Download Presentation

Datenstrukturen

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Datenstrukturen Look-Up Tabellen, Zufallszahlen, Listen, Speichermanagement und Dateiverwaltung

  2. Look-Up Tabellen: Probleme bei Spielen • Spielszenen müssen sehr oft pro Sekunden berechnet werden • Wenn es zu viele Berechnungen werden fängt das Spiel an zu „ruckeln“ • Problem ist nicht immer die Grafikkarte (bei 3D spielen) • Häufig ist KI schuld (z.B. bei Strategiespielen: viele Einheiten werden von Computer bewegt und kommandiert) wiederkehrende Operationen werden immer neu berechnet

  3. Lösung: Look Up Tabelle • Wikipedia: • In der Informatik ist eine Look-Up-Table eine Datenstruktur, meist ein (assoziatives) Array, das komplizierte Laufzeitberechnungen durch einen einfachen Zugriff auf die Datenstruktur ersetzt. Dies führt zu einem signifikanten Geschwindigkeitsgewinn, sofern die benötigten Speicherzugriffe schneller sind als die normale Berechnung. • Alle wiederkehrenden Berechnungen werden durch Look-Up Tabellen vermieden

  4. Was macht eine Look-Up Tabelle? • Vor Beginn des Spiels werden alle benötigten Werte vorberechnet • Es gibt verschiedene Typen von Look-Up Tabellen, so dass man sich vorher überlegen muss, von welcher Art (sin, cos, Quadratwurzel) diese sein muss und welche Genauigkeit diese haben muss • Es können nicht nur Funktionswerte, sondern bsplw. auch Zufallszahlen in Look-Up Tabellen gespeichert werden • Um flexibel mit Look Up Tabellen arbeiten zu können sollte man sie in Klassen einbetten

  5. Beispiel: • #include <iostream.h> • #include <math.h> • #define SAFE_DELETE(p) {if(p) {delete (p); (p)=NULL;}} • #define SAFE_DELETE_ARRAY(p) {if(p) {delete[] (p); (p)=NULL;}} • // bis hier hin nur „Vorgeplänkel“, Includen von iostream und math-Klasse und Einbinden von Makros von Heap-Speicher • //Beispiel: sinus-Tabelle

  6. class CSinLookUp • { • private: • long AnzElements; • float Genauigkeit; • float* Tabelle;

  7. public: • CSinLookUp(float Schrittweite = 1.0f) // Konstruktor • { • Genauigkeit = 1.0f/Schrittweite; • AnzElements = (long)(360*Genauigkeit); • Tabelle = new float[AnzElements]; • for(long winkel = 0; winkel < AnzElements; winkel++) • { • // Berechnung der Sinus Look-Up Tabelle • Tabelle[winkel] = sinf(winkel*Schrittweite*3.141592654f/180.0f); • } • } • ~CSinLookUp() // Destruktor • { • SAFE_DELETE_ARRAY(Tabelle) // Zerstören des Arrays • } • float ReturnSinValue(float winkel) // Zugriffsfunktion • { • if(winkel < 0.0f) • winkel += 360.0f; • else if(winkel > 360.0f) • winkel -= 360.0f; • return(Tabelle[(long)(winkel*Genauigkeit)]); • } • };

  8. Aufruf in Methode mit: • CSinLookUp* SinLookUp = new CSinLookUp(0.1f); // Schrittweite //von 0.1 • cout << "sin(45 DEG) = " << SinLookUp->ReturnSinValue(45.0f) << endl; • SAFE_DELETE(SinLookUp) // zerstören der Tabelle

  9. Zufallszahlen • Werden in einem Spiel hauptsächlich für die Variation des Spielablaufes und des Gegnerverhaltens eingesetzt • In C++ gibt es eine Funktion für Zufallszahlen • rand()-Funktion ist komfortabel für die Erzeugung von Zufallszahlen • Am komfortabelsten ist es, eine Klasse alleine für Zufallszahlen anzulegen und die Zahlen in einer Tabelle zu speichern

  10. Aufruf der Zufallszahlenmethode und Initialisierung des „Zufallsgenerators“ • int main(void) • { • // Initialisierung des Zufallsgenerators • srand(time(0)); • // dann Aufruf der Zufallszahlenfunktion • cout << frnd(-5.0f,5.0f) << endl; • }

  11. Erzeugung von Zufallszahlen mit rand()-Funktionen • Mit einfachen Inline-Funktion (hier float-Zufallszahl): • float tempFrnd; • inline float frnd(float low, float high) • { • tempFrnd = low + ( high - low ) * ( (long)rand() ) / RAND_MAX; • // RAND_MAX enthält die größtmögliche Zufallszahl • if(tempFrnd < high) • return tempFrnd; • else • return low; • } • // weiteres Beispiel im Buch (extra Klasse für Zufallszahlen)

  12. Einfach verkettete Listen • Einheit zur Speicherung und Verwaltung relevanter Daten • Besteht aus mehreren Knoten (sofern mehrere Daten vorhanden sind) • Jeder Knoten ist über einen Zeiger mit dem nächsten Knoten verbunden • Jeder Knoten ist entweder eine Strukturvariable oder ein Klassenobjekt • Erster Knoten = Head-Knoten • Letzter Knoten = Tail-Knoten

  13. Wie sieht eine einfach verkettete Liste aus? • Head  Node  Node  Node  Tail

  14. Probleme • Probleme bei Listen • Sehr unflexibel • Sehr langsam • Will man auf ein Element zugreifen, muss die gesamte Liste durchlaufen werden um das Element zu finden (es sei denn es befindet sich am Anfang) • Die Reihenfolge der abgelegten Objekte entspricht meistens nicht der Reihenfolge der im Spiel benötigten Objekte

  15. Speicherprobleme • Jedes Erzeugen von Knoten kostet Speicherplatz (mit „new“ wird Speicherplatz reserviert) • „new“ sucht nach einem Speicherblock mit geeigneter Größe • Nur wenn ein geeigneter Block gefunden wird kann Objekt angelegt werden • Sind alle gefundenen Speicherblöcke zu klein, kann Objekt nicht erzeugt werden Speicherfragmentierung

  16. Arrays lösen diese Probleme • Arrays reservieren einen bestimmten Speicherplatz • Kritik: unnötiger Speicherplatz wird verschenkt und Arrays sind zu unflexibel • Für Spieleprogrammierung gilt das nicht • Beispiel: • Spiel mit animierten Asteroiden • Obergrenze der Anzahl an Asterioden wird durch vordefiniertes Array festgelegt • Kein Nachteil, weil sowieso nur eine gewisse Anzahl gerendert und animiert werden können • Zugriff auf Array geht viel schneller als Zugriff auf Element in verketteter Liste

  17. Memory Manager • Es ist sinnvoll eine Klasse zu entwerfen die die Speicherverwaltung in einem Spiel übernimmt • Also alles in einer Memory Manager Klasse • Klasse hat vordefiniertes Array mit dem gearbeitet werden kann • Beispiel im Buch • Programmbeispiele  Tag2  Memory Manager

  18. Dateiverwaltung • Dazu zählt etwa eine Speicherfunktion für ein Spiel • Wichtige Struktur in Beispiel: • _finddata_t  Speichert alle Informationen über die Dateiarbeit • Wichtige Funktionen sind: • _findfirst( "Szenarien/*.*", &c_file ) • Untersucht ob der Ordner überhaupt existiert • _findnext( hFile, &c_file ) • Alle weiteren Dateien werden durchsucht

More Related