World
Andre Sanders
Wie bereits erwähnt, hat sich unser Team auf ein unendliches Weltmodell geeinigt. Dies lässt einerseits das Spiel realistischer erscheinen, stellt die Entwickler aber auf der anderen Seite vor zwei Probleme: Für diese Nachahmung der Realität stehen weder genug Rechenleistung noch Speicherkapazität zur Verfügung. Dies stellte sich im Laufe des Projekts als nach und nach größeres Problem dar als zuvor angenommen. Im Folgenden werden die problembezogenen Lösungsansätze bezüglich der Konstruktion der Sterne und der Asteroiden im dreidimensionalen Raum dargelegt.
Die Sterne
Die Sterne werden aus Effizienzgründen mittels Particles (siehe Kapitel 'Particles') und nicht wie zuvor durch Spheres generiert. Dies spart eine Dimension beim Rendervorgang und somit Rechenkapazität. Um den unendlichen Speicherbedarf zu umgehen haben wird auf ein nicht ganz realistisches, dafür aber sehr performantes System zurückgegriffen. Um den Spieler bauen wird eine Sphere mit einem variablen Radius gebaut. Ein ParticleHandler sorgt dafür, dass die Sterne mit einem gewissen Streufaktor nur innerhalb der ersten Sphere generiert werden. Bewegt sich der Spieler, wird jeder Stern, der als Datenstruktur lediglich aus einem Punkt besteht, in invertierte Blickrichtung des Spielers verschoben. Verlässt ein Stern den Bereich der Sphere, wird er wieder in Blickrichtung des Spielers, zufällig innerhalb der Sphere generiert.
Die Asteroiden
Als komplizierter erwies sich das effiziente Generieren von Asteroiden. Diese können nun nicht mehr als auf 2D reduzierte 3D Objekte aufgefasst werden und haben zudem noch einen viel höheren Interaktionswert als die zuvor erzeugten Sterne.
Das Modell
Ein Asteroid ist zunächst ein im Sinne der Objektorientierung eigenständiges Javascript-Objekt. Jedes Objekt besteht primär aus einer Geometrie und einer Textur welche three.js direkt zur Verfügung stellt. Im vorliegenden Fall ist die Geometrie, eine .json-Datei, die durch Blender erstellt wird und die sich die Klasse Asteroid.js direkt aus dem bereits vorgestellten Fileloader lädt. Auch die Textur wird in Blender erstellt und ebenfalls direkt geladen. Ein Material wird erstellt, welches auf die Textur gemappt und durch Phong-Shading beleuchtet wird. Anschließend wird das eigentliche Mesh aus der Geometrie und dem Material erzeugt und entsprechend eines Zufallswertes skaliert.
Eigenschaften
Damit die Asteroiden zum Leben erweckt werden, wird ihnen eine individuelle Geschwindigkeit und Rotation zugeteilt. Jedem erzeugten Asteroiden wird ein zufällig generierter Geschwindigkeitsvektor zugewiesen. Wie bei den Sternen ist dieser ein Richtungsvektor, aufzufassen als die Änderung der Position pro Renderschritt um die jeweiligen Einheiten in Richtung der entsprechenden Achse. Zusätzlich besitzt jedes Mesh eine Rotationsmatrix. Auch hier wird jedem Asteroiden bei der Erstellung ein zufälliger Vektor zugewiesen, und Einheiten in jede Richtung in jedem Renderschritt auf die aktuelle Rotation addiert. Zudem wird jedem Asteroiden bei der Erstellung noch eine Anzahl an Lebenspunkten zugeteilt.
Verhalten
Als schwierig erwies sich zudem das Erschaffen eines realistischen Verhaltens bei Wahl dieses unendlichen Weltmodells. Es können weder unendlich viele Asteroiden gerendert werden, noch können sie unendlich weit fliegen, da sonst die entsprechenden Strukturen im unendlichen Raum verloren gehen, aber dennoch Speicher und Rechenleistung verbrauchen. Um dieses Problem zu lösen, wird eine zweite, diesmal größere Sphere um den Spieler gebaut. Als Radius dient die Weite der Backplane der Kamera. Initial zum Spielstart werden n Asteroiden gleichverteilt innerhalb der zweiten Sphere erzeugt, indem die Komponenten des Positionsvektors, beschränkt durch den Radius der Sphere und den Ursprung, zufällig erzeugt werden.
Verlässt ein Asteroid die zweite Sphere aufgrund seiner eigenen Bewegung und/oder der des Spielers, wird dafür gesorgt, dass dieser wieder neu in die Sphere eintritt. Die Schwierigkeit hierbei ist allerdings die Gleichverteilung über alle Oktanden.
Benötigt ist also ein zufälliger Eintrittsvektor v auf dem Rand der Sphere, welcher der Formel
genügt und dessen Länge
= dem Radius der äußeren Sphere entspricht.
Damit nun aber nicht alle möglichen Punkte der Kugel ausgerechnet und auf ihre Länge getestet werden müssen, wird ein performanterer Weg gewählt: Man produziere sich einen Vektor v, dessen Komponenten einen zufälligen Wert zwischen 0 und 1 zugewiesen bekommen. Anschließend wird der Vektor normiert. Um jetzt Alle möglichen Punkte auf dem Rand der Sphere zu bekommen, berechnen wir Folgendes :
position.x = spieler.position.x + rnd1 * RadiusDerSphere * v.x;
position.y = spieler.position.y + rnd2 * RadiusDerSphere * v.y;
position.z = spieler.position.z + rnd3 * RadiusDerSphere * v.z;
Wobei v unser zuvor normierter Vektor ist. rnd1, rnd2 und rnd3 sind drei zufällig erzeugte Zahlen die entweder 1 oder -1 sind. Dies ist notwendig, um alle Oktanden der Sphere abzudecken. Die Gauss'sche Normalverteilung und die zufällig generierte Vorzeichen sorgen für eine realistische Eintrittsverteilung. Zuletzt wird der 'neue' Asteroid noch zufällig skaliert um tatsächlich als neuer Asteroid wahrgenommen zu werden.