Genesis3D und Delphi
Create the Game
Eine Menge „Knochenarbeit“ steht uns nun bevor, packen wir’s an. Mit CreateGame soll das Spiel „geboren“ werden, allerdings nicht ohne kräftige Wehen. Hier ist die komplette Methode:
procedure TForm1.CreateGame; var WorldScreen: geRect; // Anzeigefläche WorldName: String; // Name der BSP-Datei (Welt/Level) WorldFile: pgeVFile; // BSP-Datei (Welt/Level) begin // Anzeigefläche festlegen with WorldScreen do begin Left := 0; Right := MaxWidth - 1; Top := 0; Bottom := MaxHeight - 1; end; // Koordinaten-Matrix setzen geXForm3D_SetIdentity (@XForm); // Kamera initialisieren Camera:= geCamera_Create (2.0, @WorldScreen); if Camera = nil then ExitError('Kamera kann nicht installiert werden!'); // BSP-Datei laden WorldName := Pfad + BSP_Datei; WorldFile := geVFile_OpenNewSystem (nil, GE_VFILE_TYPE_DOS, PChar(WorldName), nil, GE_VFILE_OPEN_READONLY); // Wenn Datei ok, Welt/Level erzeugen if WorldFile <> nil then begin World := geWorld_Create(WorldFile); geVFile_Close(WorldFile); end; if World = nil then ExitError ('Welt/Level l#sst sich nicht erzeugen!'); // Welt/Level mit 3D-Engine verknüpfen if geEngine_AddWorld(Engine, World) <> OK then ExitError ('Welt/Level lässt sich nicht einbinden!'); end;
Mit WorldScreen legen wir die Anzeigefläche und ihre Maße fest:
with WorldScreen do begin Left := 0; Right := MaxWidth - 1; Top := 0; Bottom := MaxHeight - 1; end;
Diese Variable vereinbaren wir lokal in der Methode CreateGame. (Wobei der Genesis-Typ geRect ein Rechteck bezeichnet – ähnlich dem Delphi-Typ TRect.)
Bei XForm handelt es sich genau besehen um die Struktur einer Matrix. Denn die Genesis-Engine arbeitet mit Matrizen und Vektoren.
Wenn Euch diese Begriffe nicht geläufig sind, hier eine kurze Erläuterung:
- Ein Vektor ist eine Spalte bzw. Zeile mit mehreren Elementen, die hier zur Beschreibung der Lage eines Punktes im 3D-Raum dienen. Für Vektoren gibt es in Genesis3D den Typ geVec3D. mit drei Elementen X, Y und Z, die jeweils eine Koordinate eines 3D-Punktes erfassen.
- Eine Matrix (Mehrzahl: Matrizen) ist ein rechteckiges Zahlenschema aus Spalten und Zeilen – wie eine Tabelle bzw. ein Array. (Demnach wäre ein Vektor quasi eine Matrix mit nur einer Dimension).
In der 3D-Grafik gibt es verschiedene Bewegungsformen, vor allem die Verschiebung und Drehung von Objekten (oder der ganzen Spielwelt). Für eine Darstellung sind verschiedene Umrechnungsformeln nötig. Die Werte dafür werden in Matrizen gesammelt und dann ausgelesen.
Hier erhalten die Elemente der Matrix XForm erst einmal lauter Nullen und Einsen als Standwerte:
geXForm3D_SetIdentity(@XForm);
Die dabei entstandene Matrix wird auch Einheitsmatrix genannt:
1.0 | 0.0 | 0.0 | 0.0 |
0.0 | 1.0 | 0.0 | 0.0 |
0.0 | 0.0 | 1.0 | 0.0 |
0.0 | 0.0 | 0.0 | 1.0 |
Als Nächstes braucht Genesis3D eine Kamera, die auf die Anzeigefläche gerichtet ist:
Camera := geCamera_Create(2.0, @WorldScreen);
Auch hier ist es wichtig, das vorgestellte „@“ nicht zu vergessen!
Was noch immer fehlt, ist die Welt selbst. Sie wurde in aller Regel mit einem entsprechenden Editor erstellt und dabei in einer so genannten BSP-Datei gespeichert. Die muss nun geladen und ins 3D-System eingebunden werden:
WorldName := Pfad + BSP_Datei; WorldFile := geVFile_OpenNewSystem (nil, GE_VFILE_TYPE_DOS, PChar(WorldName), nil, GE_VFILE_OPEN_READONLY);
In den Parametern zu OpenNewSystem stecken auch einige Schalter für die Dateiverwaltung (um die sich Genesis hier ebenfalls kümmert).
Bei BSP handelt es sich um eine Struktur, um Objekte in einem Raum zu organisieren. Die genaue Bezeichnung ist „Binary Space Partitioning Tree“ – kurz und auf Deutsch BSP-Baum. Die Daten der Objekte werden in Baumform, also verzweigt angeordnet, und in einer Datei gespeichert, der BSP-Datei. Die 3D-Engine übernimmt die Aufgabe, diese Daten Zweig für Zweig (bzw. auch Blatt für Blatt) „abzuklappern“ und in eine grafische Darstellung umzusetzen. Im Genesis3D-Paket findet Ihr einen Editor (GEDIT.EXE), mit dem sich die passenden Welten erstellen lassen.
Ist dann die Datei mit den Daten der Spielwelt in Ordnung, kann endlich die eigentliche Welt erzeugt werden:
if WorldFile <> nil then begin World := geWorld_Create(WorldFile); geVFile_Close(WorldFile); end;
Anschließend wird die Datei WorldFile wieder geschlossen. Und nun ist die 3D-Engine bereit, sich diese Welt auch einzuverleiben:
geEngine_AddWorld(Engine, World);