DruckenMister WongFacebook

Genesis3D und Delphi

von Hans-Georg Schumann

Einleitung und Vorbereitung

Dieses Tutorial ist aus den ersten Kapiteln des Buches "Game Programming für Kids" aus dem mitp-Verlag (www.mitp.de) entstanden. Es soll zeigen, dass man mit Hilfe von Delphi auch in 3D-Welten eintauchen und sogar 3D-Games erstellen kann. Allerdings müssen wir dabei eine Game-Engine zur Hilfe nehmen, und zwar die frei verfügbare Genesis3D (über www.genesis3d.com).

An Möglichkeiten hat diese "Maschine" so viel zu bieten, dass sie sich durchaus mit kommerziellen Engines messen kann (wie sie z.B. für Spiele wie Quake, Half-Life oder Unreal eingesetzt werden).

Weil Genesis3D in C programmiert wurde, brauchen wir außerdem einen Sack voller Units, die diese Maschine auch für Delphi zum Laufen bringt (zu finden bei www.cyberspectrum.de/g4d).

  1. Bevor wir uns ans Programmieren machen, müssen wir uns die nötigen Dateien aus dem Internet holen:

    GENESIS3D120.EXE (Genesis3D-Engine-Dateien)
    www.genesis3d.com/download.php

    G4D_120_BETA6.ZIP (Genesis-Units für Delphi)
    www.cyberspectrum.de/g4d

    GENESIS_DLL_NO_LOGO.ZIP (Angepasste DLL-Datei (ohne G3D-Logo))
    www.cyberspectrum.de/g4d

    GENESIS_DLL_LOGO.ZIP (Angepasste DLL-Datei (mit G3D-Logo))
    www.cyberspectrum.de/g4d
  2. Im nächsten Schritt installiert Ihr das Genesis3D-Paket. Dann sucht Ihr im Genesis-Ordner die Treiber-Datei mit dem Namen D3DDRV.DLL und kopiert sie in den Ordner, in dem Ihr später Eure Game-Projekte unterbringen wollt. (Für alle, die kein DirectX nutzen wollen/können, gibt es noch die SOFTDRV-Dateien.)
  3. Dann müssen alle Genesis-Units in denselben Game-Ordner entpackt werden: Sie haben alle einen Namen, der mit G4D anfängt.
  4. Jetzt müsst Ihr Euch entscheiden, ob Ihr eine für Delphi angepasste GENESIS.DLL mit oder ohne Logo haben wollt, und die entsprechende ZIP-Datei entpacken. (Im einen Fall erscheint bei jeden Start eines Spiels das Genesis3D-Logo, ehe das Ganze richtig losgeht. Im anderen Fall nicht. Das hat etwas mit dem Copyright zu tun - siehe README-Datei.)
  5. Im letzten Schritt werden jetzt noch die Dateien zu diesem Tutorial aus 3dplay1.zip entpackt (G4DPLAY1.DPR, G4DGAME1.PAS, G4DGAME1.DFM, G4DDRIVER.PAS, G4DWORLD.BSP).

Erstellt wurde das Projekt mit Delphi 3, welches für den Einsatz der 3D-Engine völlig ausreicht.

Und damit kann es eigentlich losgehen. Doch ehe wir uns direkt in die Programmierung stürzen, sind ein paar Vorüberlegungen nötig. Wie soll ein 3D-Game denn aufgebaut sein? In der Regel gibt es auf jeden Fall diese drei Teile, die ich mit drei Hauptmethoden erfassen möchte:

CreateGame für das Festlegen von Startwerten, das Laden von Daten, die Belegung von Speicher
RunGame für die Abfrage von Eingaben, die Anpassung der aktuellen Spielszene, also das eigentlicher Spiel
FreeGame für Aufräumarbeiten und die Freigabe von Speicherplatz

Beginnen wir mit dem Kopf des Programms, in den diese Vereinbarungen gehören:

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
G
4D_Genesis, G4D_BaseType, G4D_XForm3D, G4D_geTypes, G4D_Vfile, G4DDriver;

Die Klasse TForm1 muss nun kräftig wachsen und bekommt dazu folgende Eigenschaften und Methoden verpasst:

type
TForm
1 = class(TForm)
procedure FormCreate (Sender: TObject);
procedure FormActivate (Sender: TObject);
procedure FormDestroy (Sender: TObject);
procedure FormClick (Sender: TObject);
private
{ Private-Deklarationen }
Engine   : pgeEngine;      // 3D-Engine
World    : pgeWorld;       // World/Level
Camera   : pgeCamera;     
// Kamera/Betrachter
Driver   : pgeDriver;      // Grafiktreiber
DMode    : pgeDriver_Mode; // Grafikmodus
XForm    : geXForm3D;      // Matrix für Welt->Betrachter
isRunning: Boolean;        // Schalter für Spiel (ein/aus)
CW8087   : DWord;          // FPU-Kontrollwert
procedure ExitError (Txt: String);
procedure CreateGame;
procedure RunGame;
procedure FreeGame;
public
{ Public-Deklarationen }
end;

Die meisten Eigenschaften sind als Zeiger (englisch: Pointer) vereinbart, denn Genesis arbeitet vorwiegend mit Adressen (an denen die jeweiligen Objekte im Speicher liegen). Das vorangestellte "ge" kürzt "Genesis" ab, und "pge" kann als "Genesis-Pointer" interpretiert werden.

Außerdem brauchen wir noch eine ganze Reihe globaler Vereinbarungen von Konstanten und Variablen:

const
Pfad      =
'.\';
BSP_Datei =
'G4DWorld.bsp';
GVersion  =
'G4DPlay1';
OK        = GE_TRUE;       // Kontrollwert für Engine-Methoden
MaxWidth  =
640;           // Max. Screenbreite
MaxHeight =
480;           // Max. Screenhöhe
MCW_EM    = DWORD(
$133f);  // für evtl. Division-durch-Null-Fehler
var
Form
1     : TForm1;     // Spiel-"Unterlage"
GHandle   : HWnd;       // Handle des Formulars
GInstance : LongInt;   
// Handle der Applikation

Die Bedeutungen dieses Arsenals von Konstanten, Variablen und TForm-Eigenschaften sind als kurze Kommentare aufgeführt. Genaueres erfahrt Ihr im weiteren Text.