11.12.2012 Aufrufe

3D Gamestudio und MySQL

3D Gamestudio und MySQL

3D Gamestudio und MySQL

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │1


<strong>3D</strong> <strong>Gamestudio</strong> <strong>und</strong> <strong>MySQL</strong><br />

von Wicht<br />

Hallo <strong>und</strong> herzlich willkommen zu meinem ersten Tutorial. In diesem werdet Ihr lernen, wie man<br />

mit einer 3dgs-Anwendung Daten an einen <strong>MySQL</strong>-Server senden kann. Und auch empfangen.<br />

Und wozu? Nun, überall da, wo jeder, der Euer Spiel benutzt, auf zentral gelagerte Daten (auch von<br />

anderen Benutzern) zugreifen kann. Eine Möglichkeit wäre z.B. ein Online-Highscore-System. Ein<br />

Nutzer sendet seine erreichte Punktezahl an eine <strong>MySQL</strong>-Datenbank <strong>und</strong> sieht sofort, welche<br />

Punkte die anderen Spieler erreicht haben. Oder wie wäre es mit einem r<strong>und</strong>enbasierten Spiel?<br />

Oder einem Chat? Oder oder oder ... Möglichkeiten gibt's genug.<br />

Was brauchen wir?<br />

Zunächst einmal das <strong>3D</strong> <strong>Gamestudio</strong>. Soweit ich weiß, können alle <strong>3D</strong>GS-Editionen DLLs<br />

ansprechen. Ist doch prima, oder? Und dann natürlich die gshttp.dll von Peacekeeper (zu finden<br />

unter http://www.peacekeeper.com/3dgs). Und die ist auch noch kostenlos. Was will man mehr.<br />

Ach ja, ein funktionierender <strong>MySQL</strong>-Server wäre auch nicht schlecht ;-)<br />

Achtung: Ich hatte Probleme, die Anweisung HTTP_POST zu verwenden. Stattdessen verwendete<br />

ich die HTTP_GET Anweisung. Außerdem müssen Sonderzeichen wie Leerzeichen, Ü,Ä,Ö usw. noch<br />

umgewandelt werden. Aus diesem Gr<strong>und</strong> habe ich die DLL um eine weitere Funktion ergänzt, die<br />

genau das macht.<br />

Die modifizierte DLL (gshttp.dll) kann unter http://www.darkware.de/3dgsmysql_tut/gshttp.dll<br />

runtergeladen werden.<br />

Wer sich zunächst einmal die ganze Materie anschauen will, ohne gleich ein Webhosting-Paket zu<br />

ordern, kann sich auch die Kombination Apache->PHP-><strong>MySQL</strong> lokal installieren. Damit kann man<br />

alles offline testen. Wie diese Programme/Module installiert werden, steht in zahlreichen<br />

Anleitungen im Internet.<br />

Wer jetzt genau aufgepasst hat, dürfte sich folgendes fragen: Nanu? Wozu auch noch den Apache-<br />

Webserver <strong>und</strong> PHP? Ich dachte immer, man kann einen <strong>MySQL</strong>-Server auch direkt ansprechen. Ihr<br />

habt recht. Natürlich geht das. Nur die meisten Webhoster wollen das aus sicherheitsrelevanten<br />

Gründen nicht <strong>und</strong> sperren den direkten externen Zugriff auf den <strong>MySQL</strong>-Server. Um aber dennoch<br />

unser Ziel zu erreichen, müssen wir PHP verwenden.<br />

Ein erster Test<br />

Jetzt wollen wir aber endlich mal was auf dem Bildschirm sehen.<br />

Erstellt eine neue 3dgs-Anwendung (nach Möglichkeit ohne die Templates zu benutzen) <strong>und</strong> kopiert<br />

die gshttp.dll in Euer Projektverzeichnis.<br />

Jetzt brauchen wir noch eine php-Datei. Die könnte etwa so aussehen:<br />

Die Datei mit dem Namen "textausgabe.php" ( den Namen könnt Ihr natürlich selbst wählen ) liegt<br />

jetzt auf meinem Webserver <strong>und</strong> kann bereits über einen Browser abgerufen werden.<br />

Bei mir sieht die URL so aus: "http://www.darkware.de/3dgsmysql_tut/textausgabe.php". Und was<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │2


macht die php-Datei? Nun, sie gibt nur einen einfachen Text aus. Mehr nicht.<br />

Im Hauptskript unserer 3dgs-Anwendung erstellen wir zunächst unser Gr<strong>und</strong>gerüst.<br />

Die Zeilen 13-24 sollten eigentlich klar sein. Interessant sind allerdings die Zeilen 4-9. Über die<br />

"dllfunction"-Anweisung wird der A6-Engine mitgeteilt, welche weiteren Funktionen ihr durch eine<br />

DLL zusätzlich zur Verfügung gestellt werden. In unserem Beispiel sind es ein Teil der Funktionen,<br />

die in der Datei gshttp.dll stehen.<br />

Und nun erweitern wir unsere main-Funktion um diese neuen Befehle.<br />

Und das kommt dabei heraus:<br />

Jetzt haben wir's schon geschafft. Unsere Anwendung greift auf eine php-Datei zu, die irgendwo im<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │3


Internet erreichbar ist <strong>und</strong> liefert deren Ergebnis zurück.<br />

Die neuen Anweisungen im Überblick:<br />

HTTP_CREATE erstellt einen neuen HTTP-Client mit einer ID-Nummer. Es können also entsprechend<br />

mehrere Clients gleichzeitig erstellt werden. Sicherheitshalber sollte man sich aber mit nur einem<br />

begnügen.<br />

HTTP_GET ruft schließlich unter der gleichen ID wie HTTP_CREATE eine Datei auf dem Webserver<br />

auf. In unserem Beispiel "http://www.darkware.de/3dgsmysql_tut/textausgabe.php".<br />

HTTP_IsWorking ist ganz wichtig. Diese Funktion überprüft, ob der Webserver mittlerweile mit<br />

seiner Arbeit fertig ist. Sollte dem nicht so sein, müssen wir eben noch etwas warten. Wer will<br />

schon mit Daten arbeiten, die noch nicht da sind ;-)<br />

HTTP_RESULTS beinhaltet schließlich das Ergebnis unserer Webserver-Anfrage. In diesem Beispiel<br />

den String "Der Gargamel mag keinen einzigen Schlumpf !!!".<br />

HTTP_FREE beendet wieder den HTTP-Client.<br />

Wichtig ist, dass bei all diesen Anweisungen immer die gleiche ID-Nummer vergeben wird. In<br />

diesem Fall ist das immer 0. Gr<strong>und</strong>legend war's das schon. Spielt etwas damit, um ein Gefühl für<br />

die neuen Befehle zu bekommen.<br />

Und der <strong>MySQL</strong>-Zugriff?<br />

Nun, diejenigen die sich mit php auskennen, dürften an dieser Stelle schon jubeln. Allen anderen<br />

sei gesagt, dass der reine <strong>MySQL</strong>-Zugriff über php realisiert wird.<br />

Und das schauen wir uns jetzt mal an.<br />

Wir legen uns erstmal eine Tabelle via phpMyAdmin an.<br />

Ein Datenbank-Tutorial liegt mir zwar fern, dennoch möchte ich auf einige wenige, aber wichtige,<br />

Dinge eingehen. Das erste Feld sollte immer eine laufende Nummer UND ein Primärschlüssel sein.<br />

Dadurch hat man die Möglichkeit, auch inhaltlich gleiche Datensätze zu unterscheiden. In diesem<br />

Screenshot könnt Ihr sehen, das das erste Feld vom Typ "int" (Ganzzahl) in der Spalte "Extra" ein<br />

"auto-increment" besitzt. Das heißt nichts weiter, als das bei jedem neuen Datensatz die Nummer<br />

des Feldes um den Wert 1 erhöht wird. Der untere Screenshot verdeutlicht das.<br />

Das Feld "3dgsmysql_tut_nr" ist genau dieses Feld mit dem Primärschlüssel <strong>und</strong> dem Extra "autoincrement".<br />

Hinweis: phpMyAdmin ist eine in der Skriptsprache PHP geschriebene Webseite, mit deren Hilfe<br />

<strong>MySQL</strong>-Datenbanken recht komfortabel verwaltet werden können.<br />

Kostenloser Download unter http://www.phpmyadmin.net.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │4


OK, wir haben also unsere Tabelle, mit mehr oder weniger sinnvollem Inhalt, angelegt. Als<br />

nächstes erstellen wir eine neue php-Datei, welche den gesamten Inhalt der Tabelle ausliest.<br />

Zunächst brauchen wir aber eine php-Datei, welche die Zugangsdaten enthält. Sie heißt<br />

"global.php".<br />

Und dann noch die php-Datei, die den Datenbankinhalt ausliest.<br />

Das obige Bild zeigt den Inhalt der Datei "textausgabe_db.php".<br />

Die Datei "textausgabe_db.php" bindet die Datei "global.php" mit Hilfe des include-Befehls ein.<br />

Also ganz analog dem include-Befehl in C-Script. Man könnte also auch die Datei "global.php"<br />

weglassen <strong>und</strong> die Zugangsdaten direkt in die Datei "textausgabe_db.php" eintragen. Mit ständig<br />

ansteigender Anzahl an php-Dateien wird man jedoch die Auslagerung der Zugangsdaten in eine<br />

separate Datei zu schätzen wissen.<br />

In den Zeilen 7-10 wird eine Datenbankverbindung aufgebaut <strong>und</strong> eine SQL-Anweisung gesendet.<br />

Die Zeile 12 hätten wir sogar weglassen können.<br />

In der Zeile 13 wird ermittelt, wieviele Datensätze als Ergebnis der Abfrage zurückgeliefert wurden.<br />

Dieser Wert wird benötigt, damit wir eine Schleife ausführen können (Zeile 15-21), um jeden<br />

einzelnen Datensatz mithilfe der echo-Anweisung auszugeben (Zeile19). Die Zeile 20 ist nur dazu<br />

da, einen Zeilenvorschub zu integrieren.<br />

Die php-Anweisung mysql_result in den Zeilen 16 <strong>und</strong> 17 liest die einzelnen Werte des aktuellen<br />

Datensatzes aus. Der erste Parameter ($res) beinhaltet das gesamte Abfrageergebnis. $i definiert<br />

den aktuellen Datensatz in der for-Schleife. Der dritte <strong>und</strong> letzte Parameter definiert des Feld.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │5


Schaut Euch dazu nochmal den unteren Screenshot an. Wenn der dritte Parameter 0 ist, dann<br />

meinen wir damit das erste Feld. Also "3dgsmysql_tut_nr". Bei einer 1 entsprechend das Feld<br />

"dw_3dgsmysql_tut_text", usw. ...<br />

In unserer C-Skipt-Datei ändert sich allerdings nicht viel. Wir haben ein weiteres Textelement,<br />

welches den Inhalt unserer "textausgabe_db.php" darstellt.<br />

HTTP_CREATE, HTTP_GET usw. sollten an dieser Stelle auch keine weiteren Fragen aufwerfen.<br />

Und hier ist das Ergebnis ...<br />

Mehr gibt's eigentlich zum empfangen von <strong>MySQL</strong>-Daten nicht zu sagen.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │6


Senden von Daten an einen <strong>MySQL</strong>-Server<br />

Auch an dieser Stelle dürften Anwender, die mit php Erfahrung haben, jubeln. Um Daten an einen<br />

<strong>MySQL</strong>-Server über eine php-Datei zu senden, werden diese einfach an das Ende der URL<br />

angehängt. Das sieht dann z.B. so aus:<br />

"http://www.darkware.de/3dgsmysql_tut/neuerdatensatz.php?user=Wicht&text=lustig".<br />

Der php-Datei "neuerdatensatz.php" werden die Variable "user" mit dem Inhalt "Wicht" <strong>und</strong> die<br />

Variable "text" mit dem Inhalt "lustig" übergeben. Und mit diesen Variablen ( <strong>und</strong> deren Werten )<br />

kann man in PHP weiterarbeiten.<br />

Wir werden unsere kleine 3dgs-Anwendung so erweitern, dass gleich 2 Werte an einen <strong>MySQL</strong>-<br />

Server übertragen werden. Dazu habe ich zunächst die Tabelle um ein weiteres Feld erweitert.<br />

Wie Ihr sehen könnt, wurde mit phpMyAdmin ein neues Feld "username" zwischen den beiden<br />

schon vorhandenen Feldern eingefügt ( Typ: varchar; Länge 60 ).<br />

Die Datei "neuerdatensatz.php, welche Daten an den <strong>MySQL</strong>-Server sendet, sieht so aus:<br />

Zeile 3: Den include-Befehl kennen wir bereits.<br />

Zeile 5: Hier wird die Variable "user" abgefangen, die wir in unserer URL angegeben haben<br />

Zeile 6: Wie Zeile 5, nur mit der Variablen "text".<br />

Hinweis: Einige von Euch werden jetzt bestimmt anmerken, dass man die Variablen <strong>und</strong> deren<br />

Werte auch mit der globalen Variable $QUERY_STRING abfragen kann. Das ist auch soweit richtig.<br />

Nur haben auch da einige Webhoster ihre eigenen Vorstellungen. Der Webhoster Strato, bei dem<br />

ich bin, "mag" diese Variable nicht. Stattdessen soll man $_GET verwenden.<br />

Die Zeilen 10-13 sollten soweit klar sein. Es wird eine Verbindung aufgebaut <strong>und</strong> die Daten werden<br />

über eine SQL-Anweisung abgeschickt. Da wir jetzt aber ein weiteres Feld in der Datenbanktabelle<br />

haben, müssen wir auch unsere "textausgabe_db.php" etwas modifizieren.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │7


Viel geändert haben wir da nicht. Interessant sind aber die Zeilen 21,23 <strong>und</strong> 24. Die Angabe "\n"<br />

steht hier für einen Zeilenvorschub. Was der genau bewirkt, seht Ihr dann, wenn Eure 3dgs-<br />

Anwendung gestartet wurde.<br />

Logischerweise müssen wir auch in der C-Skript-Datei etwas ändern.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │8


OK, gehen wir die wdl-Datei Schritt-für-Schritt durch.<br />

Zeile 04: Eine weitere Funktion wurde eingefügt. Was diese bewirkt, werden wir gleich noch<br />

sehen.<br />

Zeile 15: Ein String zum temporären abspeichern eines neuen Users.<br />

Zeile 16: Ein String zum temporären abspeichern eines neuen Textes.<br />

Zeile 17: In dieser Variable steht dann die komplette URL inkl. Datenanhang<br />

Zeile 40: Wir müssen den String in eine url-konforme Zeichenkette umwandeln ( z.B. wird aus<br />

einem Leerzeichen ein %20; aus einem ü wird ein %FC usw. )<br />

Zeile 41: Gleiches gilt auch für diese Variable.<br />

Die komplette URL sieht ohne die entsprechende Umwandlung ab Zeile 48 so aus:<br />

http://www.darkware.de/3dgsmysql_tut/neuerdatensatz.php?user=Wicht&text=Schlümpfe<br />

anschauen macht Spaß<br />

Mit Umwandlung so:<br />

http://www.darkware.de/3dgsmysql_tut/neuerdatensatz.php?user=Wicht&text=Schl%FCmpfe%20<br />

anschauen%20macht%20Spa%DF<br />

Ihr könnt das auch gerne überprüfen, indem Ihr die nicht umgewandelte URL in Euren Browser<br />

eintippt. Der Browser wandelt diese Zeile ebenfalls um. Der Rest der wdl-Datei dürfte mittlerweile<br />

verständlich sein. Mit HTTP_CREATE wird ein neuer Http-Client erzeugt. HTTP_GET ruft die URL auf.<br />

Dann warten wir, bis der Webserver alles erledigt hat (HTTP_IsWorking). Zum Schluss wird noch<br />

der HTTP-Client freigegeben. Die C-Skript-Zeilen zum abrufen von Daten haben sich derweil nicht<br />

verändert. Nach dem Start unserer 3dgs-Anwendung sehen wir dieses Bild ...<br />

Ein kontrollierender Blick via phpMyAdmin zeigt uns, dass die neuen Daten tatsächlich vorliegen ...<br />

Das war's dann auch erstmal. Ich hoffe, Euch mit diesem Tutorial halbwegs geholfen zu haben.<br />

Fehler, Anregungen, Kritiken usw. könnt Ihr gerne an info@darkware.de.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │9


Terrainerstellung mit Earthsculptor<br />

Dieses Tutorial beschäftigt sich mit der Terrainerstellung mittels dem kostenlosen Tool<br />

Earthsculptor [1] <strong>und</strong> dem Import in <strong>3D</strong> <strong>Gamestudio</strong>.<br />

Wichtig ist hierbei allerdings noch, dass dieses Verfahren nur ab der Commercial Version<br />

funktioniert, da nur ab der Com Shader möglich sind.<br />

Nachdem man Earthsculptor heruntergeladen, installiert <strong>und</strong> gestartet hat, klickt man auf File -><br />

New. Wir belassen es für den Moment bei den Standardeinstellungen. Nun sehen wir also folgendes<br />

Bild (ich habe das kleine Fenster maximiert):<br />

Wen der Nebel stört, der klickt im rechten Fenster auf „Fog" <strong>und</strong> schiebt dann den Regler „Far"<br />

nach ganz rechts. Nun haben wir also ein sehr klares Bild.<br />

In der Toolbox klicken wir nun auf den Button „Detail" (Das Karomuster).<br />

Das Fenster auf der rechten Seite sieht nun so aus:<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │10


In der oberen Reihe sehen wir 4 Buttons, die wir jeweils mit einer Textur belegen können. D.h.<br />

also, dass wir für unser Terrain bis zu 4 unterschiedliche Texturen verwenden können. Dabei gilt<br />

folgende Regel: Eine Textur überlagert immer alle Texturen auf den Buttons links von ihr. D.h. Nr. 4<br />

überlagert alles, Nr. 1 Nichts.<br />

Klicken wir nun auf „Set Detail Texture" <strong>und</strong> wählen beispielsweise „longGrass.png" als Textur aus.<br />

Das Terrain verändert sich sofort zu folgendem Bild:<br />

Nun machen wir am besten damit weiter das Terrain ein wenig zu verformen. Dazu klicken wir in<br />

der Toolbox auf das Symbol oben rechts „Terraform". Das Fenster auf der rechten Seite sieht nun<br />

so aus:<br />

Einfaches experimentieren mit den verschiedenen Tools ergibt meist schon recht schöne<br />

Ergebnisse. Hierzu gebe ich keine genauere Anleitung, da sich die meisten Dinge beim<br />

experimentieren erschließen. Die 3 Regler unter den Buttons geben den Radius des Tools, die<br />

Stärke der Veränderung <strong>und</strong> die Stärke des Randes an.<br />

Hier mal mein Beispiel Terrain nachdem ich einfach ein wenig mit den Tools herumgespielt habe:<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │11


Nun klicken wir in der Toolbox wieder auf „Detail". Wählen bei den 4 Buttons die Nr. 2 aus <strong>und</strong><br />

klicken auf „Set Detail Texture". Hier habe ich nun „cliff.png" gewählt, da ich nun die Berge<br />

bemalen wollte. Nachdem die Textur ausgewählt ist können wir nun mit dem Bemalen des Terrains<br />

beginnen. Die Regler sind ähnlich aufgebaut wie beim Verformen des Terrains.<br />

Ein kurzes Zwischenergebnis:<br />

Nun habe ich weitergemacht <strong>und</strong> auf die selbe Art <strong>und</strong> Weise die Detail-Textur 3 <strong>und</strong> 4 belegt <strong>und</strong><br />

auf das Terrain gemalt:<br />

Klicken wir nun einmal auf den Pinsel „Paint" in der Toolbox.<br />

Nun können wir im Farbauswahlfenster links eine Farbe wählen <strong>und</strong> auf das Terrain mahlen. Ich<br />

habe grün gewählt <strong>und</strong> auf das Gras gemalt. Dadurch wirkt es saftiger <strong>und</strong> frischer:<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │12


Dies stellt nun auch das Endergebnis dar. Das Wasser ist hier nur ein Gimmick <strong>und</strong> kann nicht mit<br />

exportiert werden. Klicken wir also nun auf File -> Save <strong>und</strong> speichern unser Terrain in einen<br />

beliebigen (am besten leeren) Ordner ab. In diesem Ordner haben wir nun 5 Dateien:<br />

„tutterrain.map" ist die Earthsculptor-Datei<br />

„tutterrain.png" ist die Heightmap aus der MED<br />

gleich das Terrain generieren wird<br />

„tutterrain_c0.png" ist die Colormap. Hier ist das<br />

saftige Grün unseres Grases gespeichert<br />

„tutterrrain_d0.png" ist eine RGB-Blendmap. Diese Information dient dem Shader dazu die 4<br />

Texturen richtig zu mischen.<br />

„tutterrain_I0.png" ist die Shadowmap. Hier ist also die Beleuchtung gespeichert.<br />

Nun müssen wir zuerst die Dateien umwandeln in andere Formate, damit MED damit etwas<br />

anfangen kann. Das könnte etwas kompliziert werden, da man hier einige Umwege gehen muss.<br />

Fangen wir mit der Datei „tutterrain.png" an. Diese wandeln wir am besten in eine .tga oder eine<br />

.pcx Datei um .bmp würde zwar auch gehen, aber MED interpretiert diese bei mir nicht. Daher<br />

wählen wir am besten TGS oder PCX. Das geht am einfachsten mit einem Tool wie dem<br />

EasyGraphicsConverter [2].<br />

Nun kommen wir zur Colormap, also die mit der Endung „_c0.png". Diese öffnen wir zuerst mit<br />

Windows Paint <strong>und</strong> speichern sie als BMP Datei ab. Wie bereits erwähnt hat MED Probleme mit den<br />

BMP Dateien <strong>und</strong> deswegen wandeln wir sie gleich mit dem EasyGraphicsConverter [2] in eine PCX<br />

Datei um.<br />

Mit der Blendmap „_d0.png" verfahren wir genauso. Also zuerst Paint -> Speichern als BMP -><br />

Umwandeln in eine PCX Datei.<br />

Die Shadowmap „_I0.png" öffnen wir zuerst mit Photoshop oder Paint <strong>und</strong> stellen den Bildmodus<br />

von Graustufe auf RGB um, sonst haben wir später Kanten bei den Schatten. Die Shadowmap<br />

speichern wir diesmal gleich als PCX Datei.<br />

WICHTIG! Die Blendmap <strong>und</strong> die Colormap nicht mit einem Programm wie Photoshop öffnen. Dann<br />

Photoshop <strong>und</strong> Co. Interpretieren die Transparenz in den beiden Dateien falsch <strong>und</strong> beim Speichern<br />

erhält man schlichtweg leere Dateien. Deswegen diese immer über Paint speichern, dann dieses<br />

stellt keine Transparenzen dar.<br />

So, nun haben wir also alle Dateien im PCX Format. Öffnen wir nun den MED. In MED klicken wir<br />

nun auf File -> Import -> Import Terrain from Pic Dort wählen dann als Dateiformat PCX aus <strong>und</strong><br />

öffnen die „tutterrain.pcx" (also die Datei ohne Endung).<br />

Im sich nun öffnenden Fenster stellen wir 100 x 100 Vertices ein.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │13


Bei mir ließen sich über die Regler nur 99 x 99 einstellen, was aber nicht weiter schlimm ist. Nach<br />

einem Klick auf „OK" sehen wir also nun unser in Earthsculptor erstelltes Terrain. Allerdings ist es<br />

noch ein wenig zu flach. Wir klicken also auf das Skalierungstool <strong>und</strong> skalieren das Terrain ein<br />

wenig in die Höhe, bis in etwa an das in Earthsculptor herankommt.<br />

Nun öffnen wir das Skins-Menü (Edit -> Manage Skins)<br />

Nun wählen wir den „Skin0" an <strong>und</strong> klicken auf „Skin Settings"<br />

Wir machen einen Haken bei „Texture" <strong>und</strong> klicken auf „Texture File" <strong>und</strong> dann auf „...". Hier<br />

wählen wir die Colormap aus. Also als Dateiformat PCX <strong>und</strong> dann die Datei mit der Endung<br />

„_c0.pcx".<br />

Dann klicken wir auf „New Skin" machen wieder einen Haken bei „Texture" <strong>und</strong> wählen diesmal die<br />

RGBBlendmap aus („_d0.pcx").<br />

Und das ganze wiederholen wir noch ein drittes Mal <strong>und</strong> wählen als letztes die Shadowmap<br />

(„_I0.pcx") als Textur aus.<br />

Das war's um Großen <strong>und</strong> Ganzen im MED schon. Wir speichern nun nur noch das Terrain als HMP<br />

ab.<br />

Wechseln wir nun zum WED. Nach einem Klick auf „New" wählen wir über Object -> Load Entity als<br />

Dateiformat HMP aus <strong>und</strong> öffnen unser Terrain. Dann speichern wir den Level ab <strong>und</strong> klicken dann<br />

auf File -> Map Properties. Hier klicken wir bei Script auf das Blatt Papier <strong>und</strong> wählen dann<br />

„template" aus.<br />

Jetzt können wir WED erstmal wieder schließen <strong>und</strong> öffnen die .WDL Datei, die nun in unserem<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │14


Ordner liegt. Wir bearbeiten sie so, dass sie wie folgt aussieht:<br />

Bei „path" solltet ihr den Pfad zu eurem Projektordner angeben. Die Datei „terrain_multitex.wdl"<br />

[3] kopiert ihr in euren Projektordner.<br />

Nun müssen wir noch einmal ein bisschen mit Dateiformaten <strong>und</strong> Bildern jonglieren. Dazu müssen<br />

wir zuerst einmal in Earthsculptor bei „Detail" mit der Maus über die Buttons gehen um die<br />

Dateinamen der Texturen herauszufinden.<br />

Nun müsst ihr diese Dateien (zu finden im Earthsculptor Ordner unter Textures) mit einem<br />

Konvertierungsprogramm in das PCX oder BMP Format konvertieren. Desweiteren müsst ihr darauf<br />

achten, ob die Texturen eine Größe von 256x256, 512x512 oder 1024x1024 haben.<br />

Wenn nicht, müsst ihr sie noch skalieren, ansonsten gibt es nachher unschöne schwarze Ränder<br />

auf dem Terrain. Die konvertieren Dateien legen wir ebenfalls in unseren Projektordner. Nun öffnen<br />

wir die Datei „terrain_multitex.wdl" <strong>und</strong> gehen in die Zeilen 32 – 35.<br />

Hier sind die Texturen angegeben, die nachher auf dem Terrain verwendet werden. Wir müssem<br />

hier die Texturnamen von den eben konvertierten Texturen angeben. Dabei ist Button 1 in<br />

Earthsculptor „tex3" <strong>und</strong> Button 4 „tex6".<br />

Nun haben wir es fast geschafft. Nachdem wir die Datei abgespeichert haben, öffnen wir in WED<br />

wieder unseren Level mit dem Terrain. Wir wählen es an <strong>und</strong> wählen mit einem Rechtsklick<br />

„Properties" klicken auf das Behaviour Reiter <strong>und</strong> klicken dann auf das Ordner-Symbol. Hier wählen<br />

wir dann Aktion „multi_rgb". Nun kompilieren wir den Level <strong>und</strong> bew<strong>und</strong>ern unser Endergebnis:<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │15


Ich hoffe, dass ich hiermit einen Einblick sowohl in Earthsculptor als auch in das Importieren in <strong>3D</strong><br />

<strong>Gamestudio</strong> geben konnte.<br />

Sollte ihr Fragen haben, könnt ihr die gerne im Forum oder im Gästebuch meiner Webseite<br />

loswerden.<br />

Ein Dank geht an Loopix, der den Shader für das Terrain zur Verfügung gestellt hat als auch an<br />

Nagashi, der den Shader für die Colormap modifiziert hat. DANKE!<br />

die Downloadlinks:<br />

[1] Earthsculptor<br />

[2] EasyGraphicsConverter<br />

[3] Terrain_multitex Shader<br />

[4] Beispielprojekt<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │16


Die Sache mit der Motivation<br />

Wenn ein Mann etwas ganz blödsinniges tut, so tut er es immer aus den edelsten Motiven(Oskar Wilde)<br />

Es wurde schon viel über Projektmanagement, Teamarbeit <strong>und</strong> Planung geschrieben. All dies bringt<br />

nicht viel, wenn keine oder kaum Motivation vorhanden ist, das geplante Projekt umzusetzen. In<br />

diesem Artikel soll es nun um die Mannigfaltigkeit der Motivation gehen.<br />

Hierbei muß klar sein: Nicht alles wirkt bei jedem. Aber es wird jeder in der Lage sein, aus diesem<br />

Artikel etwas nützliches für sich herauszulesen.<br />

Ich werde diesen Artikel ausnahmsweise <strong>und</strong> entgegen unserer Konventionen in der „Du" Form<br />

schreiben, da es ein recht persönliches Thema ist. Ich denke, so kommen wir am ehesten weiter.<br />

Vielleicht sollten wir erstmal beleuchten, was genau überhaupt Motivation ist. Wie entsteht der<br />

starke Drang von innen heraus, Energie in eine bestimmte Sache zu stecken, die nicht extentiell<br />

wichtig ist? Du mußt hier zwischen der inneren <strong>und</strong> der äußeren Motivation entscheiden.<br />

Innere Motivation ist schwieriger zu erzeugen, aber nachhaltiger. Äußere Motivation ist schnell<br />

„erheischt", aber verpufft auch ebenso schnell wieder. Ganz so einfach ist es natürlich nicht -<br />

jedem Psychologen würden die Haare zu Berge stehen. Beide sind eng miteinander verknüpft <strong>und</strong><br />

beeinflussen sich. Du wirst sehen, nur die Mischung macht´s.<br />

Motivation kommt von „Motiv" - ohne ein solches keine Motivation. Du kannst also nichts<br />

erzwingen. Die gute Nachricht: Das brauchst <strong>und</strong> sollst Du auch gar nicht!<br />

Die von uns allen gewünschte, innere Motivation braucht also einen Auslöser. Es können auch<br />

mehrere sein, wichtig ist nur, daß dieser Auslöser eine Perspektive gibt, an die Du glauben kannst.<br />

Hier entscheidet wiederum die eigene Skepsis <strong>und</strong> Begeisterungsfähigkeit.<br />

Motivation ist aber gleichzeitig keine auf ein Projekt bezogene Gefühlsregung. Vielmehr ist<br />

Motivation etwas allgemeines. Wenn Du in der Schule motiviert bist, trifft das auch auf viele andere<br />

Bereiche des Lebens zu. Es gilt also, sich ein entsprechendes, „motivierendes" Umfeld zu schaffen.<br />

Hier kann hoffentlich jeder auf einen gewissen Erfahrungsschatz zurückblicken. Gleichzeitig, bei<br />

ersten Erfolgserlebnissen, fährt die Skepsis zurück - neue Horizonte tun sich auf.<br />

Es gibt einige Patentrezepte, um die Motivation zu erhöhen. Du solltest Dir diejenigen raussuchen,<br />

die den größten Erfolg versprechen.<br />

Termin setzen<br />

Wenn eine Sache drängt <strong>und</strong> sie Dir wichtig ist, solltest Du Dir einen festen Termin dafür setzen.<br />

Dieser Artikel ist so entstanden. Wenn Du diesen Termin öffentlich machst, erhöht sich der Druck.<br />

Termine dürfen nicht utopisch früh gewählt sein. Langes Überziehen des Termins bis zur Erfüllung<br />

bewirken nämlich genau das Gegenteil - Demotivation. Darum solltest Du vorsichtig mit dieser<br />

Methode umgehen.<br />

Belohnungen<br />

Belohnungen müssen gar nicht mal vorgesehen sein. Oftmals entstehen sie von alleine. Die vielen<br />

Leser des Magazins sind mir z.B. Lohn genug. Allerdings kann es helfen, sich nach getaner Arbeit<br />

etwas zu gönnen.<br />

Kleine Ziele setzen<br />

Auch dies ist eine Gratwanderung. Kleine Ziele dürfen nicht unbedeutend sein, sonst verkehrt sich<br />

der Motivationseffekt ins Gegenteil. Kleine, aber ambitionierte Ziele helfen, eine große Sache<br />

überschaubar zu machen.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │17


Bei Projektarbeit: Spielen!<br />

Wenn Du mal wieder gar keine Lust hast, an einem Spiel weiterzumachen, so spiele es eine Weile.<br />

Meist wird Dir dann bewußt, wie viel Arbeit schon drin steckt. Und es gehört schon eine ordentliche<br />

Portion Melancholie dazu, dann nicht weiterzumachen. Auch hier gibt es zwei Seiten der Medaille:<br />

Vielleicht fallen Dir lauter Baustellen auf, die Dich in diesem Moment überfordern. Du sagst Dir:<br />

Wie soll ich das alles nur schaffen? Nun, bevor Du mit falschem Stolz <strong>und</strong> überzogenen<br />

Erwartungen nicht weitermachst, schmeiße lieber einige Features raus. Du wirst sehen, wie der<br />

Druck von Dir weicht. Das ist kein Gr<strong>und</strong>, wieder unmotiviert zu werden. Im Gegenteil: Du beweißt<br />

ges<strong>und</strong>en Menschenverstand, indem Du alte Meinungen <strong>und</strong> Vorurteile revidierst! Vor drei Jahren<br />

warst Du vielleicht der Meinung, es muß ein MMORPG werden. Es ist nicht schlimm, wenn es doch<br />

nur ein normales RPG wird.<br />

Kommunikation<br />

Viele User im Forum reden gerne - sei es über Chat, Mails oder PM. Tausche Dich mit ihnen aus.<br />

Nimm das Zusammengehörigkeitsgefühl auf, sauge es ein! Sich gegenseitig zu motivieren ist zwar<br />

nicht so nachhaltig wie die Eigenmotivation - aber es hängt zusammen. Durch konstruktive<br />

Gespräche steigt Deine Laune ebenso wie Deine innere Motivation. Und zwar unterbewußt.<br />

Motiviere Dich bewußt<br />

Das ist vielleicht etwas hölzern ausgedrückt, darum gebe ich Dir ein Beispiel: Wenn Dir jemand ein<br />

Kompliment macht - nimm es an. Sag´"Danke! Das ist nett von Dir!". Das hat viele positive<br />

Effekte. Dein Selbstbewußtsein wird aufgebaut <strong>und</strong> Dein Gegenüber freut sich. Viel mehr, als wenn<br />

Du in falscher Bescheidenheit sagst: „Na ja, so toll ist es auch nicht..."<br />

Setz´ Dich nicht unter Druck<br />

Wenn Du gar keine Lust hast, solltest Du keinen Termin setzen oder mit dem Kopf durch die Wand<br />

wollen. Das ist okay <strong>und</strong> kein Gr<strong>und</strong> zu verzweifeln. Motivation kann man nicht erzwingen. Man<br />

kann sie sich nur „erfühlen". Umgebe Dich nicht mit Schwarzsehern. Sei Dir immer sicher, das alles<br />

klappt - dann gibt es keine Gründe mehr verzweifelt zu sein. Du kannst es, Du machst es <strong>und</strong> Du<br />

weißt es. Wo ist das Problem? Leg´ die Beine hoch, Du schaffst es doch sowieso!<br />

Lass Dich nicht runterziehen<br />

Wenn Du im Team arbeitest, dann steht <strong>und</strong> fällt die Motivation. Das ist ganz natürlich <strong>und</strong> kein<br />

Prozess, den man so einfach aufhalten kann. Stattdessen solltest Du mit gutem Beispiel voran<br />

gehen <strong>und</strong> signalisieren, daß Du an den Erfolg des Teams glaubst. In guten wie in schlechten<br />

Zeiten. Wenn Du als Konstante fungierst, werden andere Teammitglieder davon mitgerissen.<br />

Drohungen, Beschwerden <strong>und</strong> ähnliches helfen nicht. Das mußte ich selbst auch schon feststellen.<br />

Häng´ das Projekt nicht am Team auf. Wenn Peter das getan hätten, wäre Mausgame nicht so weit,<br />

wie es ist.<br />

Einfach anfangen!<br />

Den inneren Schweineh<strong>und</strong> zu überwinden ist nicht einfach. Ich mußte das auch tun, um diesen<br />

Artikel zu schreiben. Aber siehe da: Es macht Spaß! Ich bin völlig überrascht von mir selbst! Das<br />

kannst Du auch. Überrasche Dich immer mal wieder selbst, es ist fast so schön als wenn das<br />

andere tun.<br />

Nimm´ Dich nicht so ernst<br />

Das kannst Du Dir nicht oft genug sagen. Wenn irgendwelche Steine im Weg liegen <strong>und</strong> Du<br />

stolperst, lach drüber! Du kannst nur draus lernen <strong>und</strong> gestärkt daraus hervorgehen. Die<br />

wenigsten Stolpersteine sollte man persönlich nehmen. Betrachte sie als Herausforderung,<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │18


vielleicht sogar als leicht tragischen Gag. Das nimmt ihnen die Härte <strong>und</strong> sorgt dafür, daß Du ihnen<br />

nicht „ohnmächtig" gegenüberstehst.<br />

Ich bin mir sicher, daß dieser Artikel einiges in Dir bewirken wird. Lass es raus!<br />

Ich hätte auch schreiben können, daß ich HOFFE, daß dieser Artikel weiterhilft. Dem ist nicht so.<br />

Stattdessen bin mir einfach sicher, daß er hilft. Basta. Ein schönes Gefühl. ;-)<br />

Viel Spaß beim ausprobieren wünscht,<br />

Torsten Fock<br />

www.vulkanware.de<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │19


Einfache Physik durch Event Funktionen ohne<br />

Newton <strong>und</strong> dergleichen<br />

Ich möchte in diesem Tutorial mit Ihnen ein paar einfache Physik Bewegungen programmieren um<br />

Objekte durch Berührung oder Beschuss zu bewegen.<br />

Mann möge mir verzeihen wenn ich nicht die Befehle my.poligon = on <strong>und</strong> c_trace für<br />

poligongenaue Abtastung verwende, aber da ich nur eine Sybex Version besitze sind diese Befehle<br />

bei mir nicht möglich <strong>und</strong> ich möchte hier keine Skripte bzw. Befehle abdrucken die ich nicht<br />

getestet habe.<br />

Inhalt:<br />

1. Vorstellung des Skriptes<br />

2. Vorstellung der Aktion<br />

2.1 Die Aktion "entity_1"<br />

3. Vorstellung der Funktionen<br />

3.1 Die Funktion "function ent_col_event1();" // Event Funktion der Entity<br />

3.2 Die Funktion "function physik_1();" // Hauptfunktion der Entity<br />

3.3 Die Funktion "function Max_Min_Berechnung();" // Grenzen der Bo<strong>und</strong>ing Box<br />

3.4 Die Funktion "function Abstand_zum_Boden();" // Abstandsberechnung zum Boden<br />

3.5 Die Funktion "function Abstand_Ecken();" // Abstandsberechnung der Ecken<br />

3.6 Die Funktion "function Schieflage();" // Schieflage der Entity über Abgr<strong>und</strong><br />

3.7 Die Funktion "function Anziehungskraft();" // Anziehungskraftberechnung der Entity<br />

3.8 Die Funktion "function Drift();" // Drift der Entity bei Schieflage<br />

3.9 Die Funktion "function Kraftfaktor();" // Kraftfaktorberechnung bei Berührung<br />

3.10 Die Funktion "function Bewegung();" // Bewegung der Entity<br />

Bestimmte Variablen <strong>und</strong> die Handle der Entities werden im Skript in Arrays abgespeichert. Sollte<br />

Ihnen die Verwendungsweise von Arrays nicht geläufig sein, können Sie in diversen Publikationen<br />

<strong>und</strong> Tutorials mehr über diese Art der Speicherung erfahren. Im 3dgsMagazin No.2 finden Sie auch<br />

ein Tutorial über die Benutzung von Arrays. Ich werde hier nicht im Einzelnen auf die<br />

Funktionsweise von Arrays eingehen da dies den Rahmen hier sprengen würde.<br />

Sämtliche Funktionen funktionieren auch mit dem Player der Template Skripte. Sie müssen nicht<br />

erst einen eigenen Player-Skript schreiben.<br />

1. Vorstellung des Skriptes<br />

Zuerst einmal möchte ich Ihnen das Skript vorstellen. Danach werde ich im Einzelnen auf die<br />

verschiedenen Aktionen <strong>und</strong> Funktionen eingehen um Ihnen die Funktionsweise näher zu bringen.<br />

//////////////////////////////////////////<br />

//// Definitionen für Bewegungskörper ////<br />

//////////////////////////////////////////<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │20


define _gewicht,skill1;<br />

define _entity_x,skill2;<br />

define _entity_y,skill3;<br />

define _entity_z,skill4;<br />

define _MaxMin_x,skill8;<br />

define _MaxMin_y,skill9;<br />

define _MaxMin_z,skill10;<br />

//define _speed,skill11; // Noch nicht in Verwendung<br />

//define _speed_x,skill11; // Noch nicht in Verwendung<br />

//define _speed_y,skill12; // Noch nicht in Verwendung<br />

//define _speed_z,skill13; // Noch nicht in Verwendung<br />

define _dist_floorR,skill14;<br />

define _dist_floorL,skill15;<br />

define _dist_floorF,skill16;<br />

define _dist_floorB,skill17;<br />

define _dist_floorM,skill18;<br />

define _ABSOLDIS,skill34;<br />

define _ABSOLDIS_X,skill34;<br />

define _ABSOLDIS_Y,skill35;<br />

define _ABSOLDIS_Z,skill36;<br />

define _floornormal1,skill37;<br />

define _floornormal1_X,skill37;<br />

define _floornormal1_Y,skill38;<br />

define _floornormal1_Z,skill39;<br />

define _f_drift,skill40;<br />

define _move_x,skill41;<br />

define _move_y,skill42;<br />

define _force,skill43;<br />

define _move_force,skill44;<br />

define _Bewegung_Vert,skill45;<br />

define _Bodenhöhe,skill46;<br />

define ent_id,skill47;<br />

define entity_id,skill48;<br />

//////////////////////////////////////////////////////////<br />

//// Variablen in Verbindung mit Templates ausblenden ////<br />

//////////////////////////////////////////////////////////<br />

var force[3] =0,0,0;<br />

var friction;<br />

var slopefac;<br />

var gravity;<br />

///////////////////<br />

//// Variablen ////<br />

///////////////////<br />

var temp_1;<br />

var temp_2;<br />

var t;<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │21


}<br />

var ent_nr;<br />

/////////////////////////////<br />

//// String <strong>und</strong> Entities ////<br />

/////////////////////////////<br />

entity* Koerper;<br />

////////////////<br />

//// Arrays ////<br />

////////////////<br />

var ent_array1[8000];<br />

////////////////////<br />

//// Funktionen ////<br />

////////////////////<br />

function ent_col_event1(); // Event Funktion der Entity<br />

function Max_Min_Berechnung(); // Grenzen der Bo<strong>und</strong>ing Box<br />

function Abstand_zum_Boden(); // Abstandsberechnung zum Boden<br />

function Abstand_Ecken(); // Abstandsberechnung der Ecken der Entity zum Boden<br />

function Schieflage(); // Schieflage der Entity über Abgr<strong>und</strong><br />

function Anziehungskraft(); // Anziehungskraftberechnung der Entity<br />

function Drift(); // Drift der Entity bei Schieflage<br />

function Kraftfaktor(); // Kraftfaktorberechnung bei Berührung der Entity<br />

function Bewegung(); // Bewegung der Entity<br />

//uses _Gewicht,_entity_x,_entity_y,_entity_z,<br />

action entity_1<br />

{<br />

Koerper = my;<br />

t += 10;<br />

ent_nr = t;<br />

my.ent_id = ent_nr;<br />

my.fat = off;<br />

my.narrow = on;<br />

//my.passable = on;<br />

my.push = 0;<br />

if (my._gewicht == 0)<br />

{my._gewicht = 10;}<br />

my.event = ent_col_event1;<br />

my.enable_sonar = on;<br />

my.enable_shoot = on;<br />

my.enable_block = on;<br />

my.enable_entity = on;<br />

my.enable_impact = on;<br />

my.enable_push = on;<br />

my.enable_click = on;<br />

physik_1();<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │22


function ent_col_event1()<br />

{<br />

if(event_type == event_impact)<br />

{<br />

}<br />

if(my == null){return;}<br />

if(you == null){return;}<br />

ent_nr = my.ent_id;<br />

//// Koordinaten Trefferpunkt ////<br />

ent_array1[ent_nr*10+0] = target[0];<br />

ent_array1[ent_nr*10+1] = target[1];<br />

ent_array1[ent_nr*10+2] = target[2];<br />

//// Koordinaten auslösende Entity ////<br />

ent_array1[ent_nr*10+3] = you.x;<br />

ent_array1[ent_nr*10+4] = you.y;<br />

ent_array1[ent_nr*10+5] = you.z;<br />

//// Gewicht der Entity ////<br />

if(you.skill1 == 0){temp = 10;}<br />

if(player == you){temp = 10;}<br />

ent_array1[ent_nr*10+6] = temp;<br />

//// Geschwindigkeit der Entity ////<br />

if(you.skill11 == 0){you.skill11 = 10;}<br />

ent_array1[ent_nr*10+7] = you.skill11;<br />

//// Winkel Aufprallrichtung ////<br />

vec_diff(temp_1,target,you.x);<br />

//// Abprallwinkel ////<br />

vec_to_angle (temp,normal);<br />

ent_array1[ent_nr*10+8] = temp.pan;<br />

ent_array1[ent_nr*10+9] = temp.tilt;<br />

//// Schiebende Kraft ////<br />

my._force = ent_array1[ent_nr*10+6] * ent_array1[ent_nr*10+7];<br />

if(event_type == event_shoot)<br />

{<br />

if(my == null){return;}<br />

if(you == null){return;}<br />

ent_nr = my.ent_id;<br />

//// Koordinaten Trefferpunkt ////<br />

ent_array1[ent_nr*10+0] = target[0];<br />

ent_array1[ent_nr*10+1] = target[1];<br />

ent_array1[ent_nr*10+2] = target[2];<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │23


}<br />

}<br />

//// Koordinaten auslösende Entity ////<br />

ent_array1[ent_nr*10+3] = you.x;<br />

ent_array1[ent_nr*10+4] = you.y;<br />

ent_array1[ent_nr*10+5] = you.z;<br />

//// Gewicht der Entity ////<br />

temp = you.skill4;<br />

if(player == you){temp = 10;}<br />

ent_array1[ent_nr*10+6] = temp;<br />

//// Geschwindigkeit der Entity ////<br />

ent_array1[ent_nr*10+7] = you.skill5/2;<br />

//// Winkel Aufprallrichtung ////<br />

vec_diff(temp_1,target,you.x);<br />

//// Abprallwinkel ////<br />

vec_to_angle (temp,normal);<br />

ent_array1[ent_nr*10+8] = temp.pan;<br />

ent_array1[ent_nr*10+9] = temp.tilt;<br />

//// Schiebende Kraft ////<br />

my._force = ent_array1[ent_nr*10+6] * ent_array1[ent_nr*10+7];<br />

if (event_type == event_click) // Noch nicht in Verwendung<br />

{<br />

}<br />

koerper = me;<br />

function physik_1()<br />

{<br />

Max_Min_Berechnung();<br />

if(my._entity_x == 0)<br />

{<br />

}<br />

my._entity_x = my._MaxMin_x;<br />

if(my._entity_y == 0)<br />

{<br />

}<br />

my._entity_y = my._MaxMin_y;<br />

if(my._entity_z == 0)<br />

{<br />

}<br />

while(1)<br />

{<br />

my._entity_z = my._MaxMin_z;<br />

Abstand_zum_Boden();<br />

Abstand_Ecken();<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │24


}<br />

}<br />

Anziehungskraft();<br />

Schieflage();<br />

Drift();<br />

Kraftfaktor();<br />

Bewegung();<br />

wait(1);<br />

function Max_Min_Berechnung()<br />

{<br />

}<br />

my._MaxMin_x = (my.max_x - my.min_x);<br />

my._MaxMin_y = (my.max_y - my.min_y);<br />

my._MaxMin_z = (my.max_z - my.min_z);<br />

function Abstand_zum_Boden()<br />

{<br />

richten<br />

richten<br />

}<br />

vec_set (temp,nullvector);<br />

vec_set(temp,my.x);<br />

temp.z -=4000;<br />

vec_set(temp_1,my.x);<br />

temp_1.z = my.z - ((my._entity_z)/2);<br />

trace_mode = ignore_me + ignore_sprites + ignore_models + scan_texture;<br />

my._BODENHÖHE = trace(temp_1,temp);<br />

// my._BODENHÖHE beinhaltet die Entfernung zum Boden<br />

my._floornormal1_X = NORMAL.X;// my._floornormal auf die Normale des Bodens<br />

my._floornormal1_Y = NORMAL.Y;// my._floornormal auf die Normale des Bodens<br />

my._floornormal1_Z = NORMAL.Z;<br />

function Abstand_Ecken()<br />

{<br />

//// Trace von Mitte nach unten ////<br />

vec_set(temp.x,my.x);<br />

temp.z = my.z - (my._entity_z)/2;<br />

trace_mode = ignore_me + ignore_passable + ignore_passents;<br />

my._dist_floorM = trace(temp.x,vector(temp.x,temp.y,temp.z-500));<br />

//// Trace von links nach unten ////<br />

vec_set(temp.x,vector(0,(my._entity_y/2),0));<br />

vec_rotate(temp.x,vector(my.pan,0,0));<br />

vec_add(temp.x,my.x);<br />

temp.z = my.z - (my.max_z - my.min_z)/2;<br />

trace_mode = ignore_me + ignore_passable + ignore_passents;<br />

my._dist_floorL = trace(temp.x,vector(temp.x,temp.y,temp.z-500));<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │25


}<br />

//// Trace von rechts nach unten ////<br />

vec_set(temp.x,vector(0,-(my._entity_y/2),0));<br />

vec_rotate(temp.x,vector(my.pan,0,0));<br />

vec_add(temp.x,my.x);<br />

temp.z = my.z - (my._entity_z)/2;<br />

trace_mode = ignore_me + ignore_passable + ignore_passents;<br />

my._dist_floorR = trace(temp.x,vector(temp.x,temp.y,temp.z-500));<br />

//// Trace von vorne nach unten ////<br />

vec_set(temp.x,vector((my._entity_x/2),0,0));<br />

vec_rotate(temp.x,vector(my.pan,0,0));<br />

vec_add(temp.x,my.x);<br />

temp.z = my.z - (my._entity_z)/2;<br />

trace_mode = ignore_me + ignore_passable + ignore_passents;<br />

my._dist_floorF = trace(temp.x,vector(temp.x,temp.y,temp.z-500));<br />

//// Trace von hinten nach unten ////<br />

vec_set(temp.x,vector(-(my._entity_x/2),0,0));<br />

vec_rotate(temp.x,vector(my.pan,0,0));<br />

vec_add(temp.x,my.x);<br />

temp.z = my.z - (my._entity_z)/2;<br />

trace_mode = ignore_me + ignore_passable + ignore_passents;<br />

my._dist_floorB = trace(temp.x,vector(temp.x,temp.y,temp.z-500));<br />

function Schieflage()<br />

{<br />

temp = abs(my._dist_floorF - my._dist_floorB);<br />

if(temp 5 &&<br />

my._dist_floorF > 5 && my._dist_floorB > 5)<br />

{<br />

}<br />

return;<br />

if (my._dist_floorL >= 5)<br />

{<br />

temp = atan(my._dist_floorL/(my._entity_y/2));<br />

if(temp > abs(my.roll)) // Absolutberechnung da Roll negativ ist<br />

{<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │26


}<br />

}<br />

}<br />

my.roll -= 1 * time;<br />

if (my._dist_floorR >= 5)<br />

{<br />

}<br />

temp = atan(my._dist_floorR/(my._entity_y/2));<br />

if(temp > my.roll)<br />

{<br />

}<br />

my.roll += 1 * time;<br />

if (my._dist_floorF >= 5)<br />

{<br />

}<br />

temp = atan(my._dist_floorF/(my._entity_x/2));<br />

if(temp > abs(my.tilt)) // Absolutberechnung da Tilt negativ ist<br />

{<br />

}<br />

my.tilt -= 1 * time;<br />

if (my._dist_floorB >= 5)<br />

{<br />

}<br />

temp = atan(my._dist_floorB/(my._entity_x/2));<br />

if(temp > my.tilt)<br />

{<br />

}<br />

my.tilt += 1 * time;<br />

function Anziehungskraft()<br />

{<br />

if (my._dist_floorM>5&&my._dist_floorL>5&& my._dist_floorR>5&&my._dist_floorF>5&&<br />

my._dist_floorB > 5) // in der Luft?<br />

{<br />

}<br />

force.z = -5; // Schwerkraft<br />

friction = 0.1; // Luftwiederstand<br />

// Geschwindigkeit vertikal<br />

my._Bewegung_Vert = time*force.z + max(1-time*friction,0)*my._Bewegung_Vert;<br />

my._absoldis_Z = time * my._Bewegung_Vert;<br />

if (my._BODENHÖHE < 5 && my._BODENHÖHE > 0)<br />

{<br />

my._Bewegung_Vert = 0;<br />

my._absoldis_Z = 0;<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │27


}<br />

}<br />

if (my._BODENHÖHE < 0 )<br />

{<br />

}<br />

function Drift()<br />

{<br />

}<br />

force.z = -0.5 * my._BODENHÖHE; // Boden-Elastizität<br />

friction = 0.5; // Bodenreibung<br />

// Geschwindigkeit vertikal<br />

my._Bewegung_Vert = time*force.z + max(1-time*friction,0)*my._Bewegung_Vert;<br />

my._absoldis_Z = time * my._Bewegung_Vert;<br />

//// Kippbereich der Objekte ////<br />

if (my._dist_floorM 0 || my._move_force > 0)<br />

{<br />

}<br />

my._move_force = my._force * time + max(1-time*0.5,0)*my._move_force;<br />

my._force = 0;<br />

function Bewegung()<br />

{<br />

ent_nr = my.ent_id;<br />

if(my._move_force > 0)<br />

{<br />

my._absoldis_X =<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │28


(cos(ent_array1[ent_nr*10+8])*(my._move_force/ent_array1[ent_nr*10+6]))*time;<br />

my._absoldis_Y =<br />

(sin(ent_array1[ent_nr*10+8])*(my._move_force/ent_array1[ent_nr*10+6]))*time;<br />

}<br />

if(my._move_force


Diese Zuweisung brauchen wir allerdings erst in einem späteren Tutorial, wenn es darum geht<br />

diverse Kisten <strong>und</strong> dergleichen zu stapeln. Dann haben wir die Erhöhung der Array Variable. Ich<br />

werde verschiedene Parameter, wie Kollisionspunkt, Kollisionsgeschwindigkeit <strong>und</strong> diverse andere<br />

Angaben in einem Array speichern um Entity Skills zu sparen.<br />

In den nächsten zwei Zeilen, ent_nr = t <strong>und</strong> my.ent_id = ent_nr speichere ich den Anfangsarray<br />

jeder Entity in einem Entity Skill ab um später jeder Zeit wieder darauf zugreifen zu können. Dann<br />

schalte ich die dicke Hülle der Entity ab <strong>und</strong> die dünne ein. Gefolgt von der vorher Besprochenen<br />

Gewichtszuweisung von 10 kg wenn keine Eingabe im WED statt gef<strong>und</strong>en hat. Die Zuweisung der<br />

Event Funktion, die Sensibilisierung für gewisse Event Aktionen <strong>und</strong> der darauffolgende Sprung zur<br />

Hauptfunktion physik_1 beendet dann unsere Aktion entity_1.<br />

3. Vorstellung der Funktionen<br />

3.1 Die Funktion "ent_col_event1()"<br />

function ent_col_event1()<br />

{<br />

if(event_type == event_impact)<br />

{<br />

if(my == null){return;}<br />

if(you == null){return;}<br />

ent_nr = my.ent_id;<br />

//// Koordinaten Trefferpunkt ////<br />

ent_array1[ent_nr*10+0] = target[0];<br />

ent_array1[ent_nr*10+1] = target[1];<br />

ent_array1[ent_nr*10+2] = target[2];<br />

//// Koordinaten auslösende Entity ////<br />

ent_array1[ent_nr*10+3] = you.x;<br />

ent_array1[ent_nr*10+4] = you.y;<br />

ent_array1[ent_nr*10+5] = you.z;<br />

//// Gewicht der Entity ////<br />

if(you.skill1 == 0){temp = 10;}<br />

if(player == you){temp = 70;}<br />

ent_array1[ent_nr*10+6] = temp;<br />

//// Geschwindigkeit der Entity ////<br />

if(you.skill11 == 0){you.skill11 = 10;}<br />

ent_array1[ent_nr*10+7] = you.skill11;<br />

//// Winkel Aufprallrichtung //// // Wird noch nicht benötigt<br />

vec_diff(temp_1,target,you.x);<br />

//// Abprallwinkel ////<br />

vec_to_angle (temp,normal);<br />

ent_array1[ent_nr*10+8] = temp.pan;<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │30


}<br />

}<br />

ent_array1[ent_nr*10+9] = temp.tilt;<br />

//// Schiebende Kraft ////<br />

my._force = ent_array1[ent_nr*10+6] * ent_array1[ent_nr*10+7];<br />

if(event_type == event_shoot)<br />

{<br />

}<br />

if(my == null){return;}<br />

if(you == null){return;}<br />

ent_nr = my.ent_id;<br />

//// Koordinaten Trefferpunkt ////<br />

ent_array1[ent_nr*10+0] = target[0];<br />

ent_array1[ent_nr*10+1] = target[1];<br />

ent_array1[ent_nr*10+2] = target[2];<br />

//// Koordinaten auslösende Entity ////<br />

ent_array1[ent_nr*10+3] = you.x;<br />

ent_array1[ent_nr*10+4] = you.y;<br />

ent_array1[ent_nr*10+5] = you.z;<br />

//// Gewicht der Entity ////<br />

temp = you.skill4;<br />

ent_array1[ent_nr*10+6] = temp;<br />

//// Geschwindigkeit der Entity ////<br />

ent_array1[ent_nr*10+7] = you.skill5/2;<br />

//// Winkel Aufprallrichtung ////<br />

vec_diff(temp_1,target,you.x);<br />

//// Abprallwinkel ////<br />

vec_to_angle (temp,normal);<br />

ent_array1[ent_nr*10+8] = temp.pan;<br />

ent_array1[ent_nr*10+9] = temp.tilt;<br />

//// Schiebende Kraft ////<br />

my._force = ent_array1[ent_nr*10+6] * ent_array1[ent_nr*10+7];<br />

if (event_type == event_click) // Noch nicht in Verwendung<br />

{<br />

}<br />

koerper = me;<br />

Die erste If-Anweisung bezieht sich auf die Kollision mit einer anderen Entity. Gefolgt von zwei<br />

Anweisungen die sich auf die my- <strong>und</strong> you-Entity beziehen, dort wird bei nicht vorhanden sein<br />

einer der beiden Entities die Funktion sofort verlassen um etwaige Empty Pointer Fehlermeldungen<br />

aus dem Weg zu gehen. Danach kommt der Aufruf der Array Nummer aus dem Entity Skill um die<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │31


ganzen speicherbaren Werte auch in den richtigen Array Bereich zu speichern <strong>und</strong> nicht etwa in<br />

den Array Bereich einer anderen Entity die mit dieser Kollision garnichts zu tun hatte.<br />

In den folgenden Array Variablen wird gespeichert, der Kollisionspunkt an der Entity, die X-, Y- <strong>und</strong><br />

Z-Werte der kollidierenden Entity, das Gewicht <strong>und</strong> die Geschwindigkeit der Entity.<br />

Desweiteren die Winkelrichtung, die sich hier auf die Normale der Oberfläche beziehen. Und dann<br />

noch die Berechnung der Kraft die auf die Entity wirkt. Die Kraft berechnet man ja bekanntlich, wie<br />

jeder weiss der schon einmal Physik in der Schule gehabt hat, aus dem Produkt von Masse <strong>und</strong><br />

Beschleunigung.<br />

my._force = ent_array1[ent_nr*10+6]*ent_array1[ent_nr*10+7]<br />

Was bedeutet, meine Geschwindigkeit ist dein Gewicht mal deine Beschleunigung. In der If-<br />

Anweisung der shoot-Abfrage befinden sich die selben Berechnungen <strong>und</strong> Abfragen die wir vorher<br />

schon besprochen haben. Nur die Gewichts- <strong>und</strong> Geschwindigkeitsangaben der Entity beziehen sich<br />

hier auf andere Skill Werte. Für die Gewichtsberechnung ist hier der Skill4 <strong>und</strong> für die<br />

Geschwindigkeitsberechnung der Skill5 der kollidierenden Entity zuständig.<br />

Diese Skills finden auch in den Templates Verwendung. Deshalb habe ich sie auch hier verwendet<br />

um Template Benutzer auch die Möglichkeit zu geben dieses Skript hier zu verwenden. Die letzte<br />

If-Abfrage bezieht sich auf das Anklicken der Entity mit der linken Maustaste. Diese Abfrage findet<br />

erst in einem späteren Tutorial Verwendung, wenn wir versuchen diverse Kisten oder Tonnen <strong>und</strong><br />

dergleichen zu stapeln.<br />

3.2 Die Funktion "physik_1()"<br />

function physik_1()<br />

{<br />

Max_Min_Berechnung();<br />

if(my._entity_x == 0)<br />

{<br />

}<br />

my._entity_x = my._MaxMin_x;<br />

if(my._entity_y == 0)<br />

{<br />

}<br />

my._entity_y = my._MaxMin_y;<br />

if(my._entity_z == 0)<br />

{<br />

}<br />

while(1)<br />

{<br />

my._entity_z = my._MaxMin_z;<br />

Abstand_zum_Boden();<br />

Abstand_Ecken();<br />

Anziehungskraft();<br />

Schieflage();<br />

Drift();<br />

Kraftfaktor();<br />

Bewegung();<br />

wait(1);<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │32


}<br />

}<br />

Die Hauptfunktion unserer Entity beinhaltet den Sprung in sämtliche andere Funktionen der Entity.<br />

Ich wähle immer diesen Weg der Hauptfunktion <strong>und</strong> den Sprung in die Unterfunktionen da es mir<br />

auf diesem Wege möglich ist eventuell bei bestimmten Aktionen verschiedene Funktionen der<br />

Entity zu überspringen. Ich gehe hier nicht im einzelnen auf die verschiedenen Funktionssprünge<br />

ein da wir die Funktionen noch genau besprechen werden.<br />

Hier nur eine grobe Auflistung der Funktionen <strong>und</strong> für welche Berechnungen sie zuständig sind.<br />

function Max_Min_Berechnung(); // Grenzen der Bo<strong>und</strong>ing Box<br />

function Abstand_zum_Boden(); // Abstandsberechnung zum Boden<br />

function Abstand_Ecken(); // Abstandsberechnung der Ecken der Entity zum Boden<br />

function Anziehungskraft(); // Anziehungskraftberechnung der Entity<br />

function Schieflage(); // Schieflage der Entity über Abgr<strong>und</strong><br />

function Drift(); // Drift der Entity bei Schieflage<br />

function Kraftfaktor(); // Kraftfaktorberechnung bei Berührung der Entity<br />

function Bewegung(); // Bewegung der Entity<br />

Unterhalb des Funktionssprungs zur Max-Min Berechnung finden Sie die Zuweisung der Max-Min<br />

Parameter in die Entity_X Skills, diese Zuweisung findet statt wenn im WED keine Angaben der<br />

Ausdehnung der Entity gemacht werden.<br />

3.3 Die Funktion "Max_Min_Berechnung()"<br />

function Max_Min_Berechnung()<br />

{<br />

my._MaxMin_x = (my.max_x - my.min_x);<br />

my._MaxMin_y = (my.max_y - my.min_y);<br />

my._MaxMin_z = (my.max_z - my.min_z);<br />

}<br />

Hier berechnen wir die Grenzen der Bo<strong>und</strong>ing Box der Entity. Diese Berechnung könnte man sich<br />

sparen, sie ist nicht unbedingt nötig. Aber dann müsste man jedesmal wenn man die Grösse<br />

feststellen will immer wieder die Berechnung my.max-my.min durchführen. So spare ich mir das<br />

<strong>und</strong> schreibe es in einen Entity Skill.<br />

3.4 Die Funktion "Abstand_zum_Boden()"<br />

function Abstand_zum_Boden()<br />

{<br />

vec_set (temp,nullvector);<br />

vec_set(temp,my.x);<br />

temp.z -=4000;<br />

vec_set(temp_1,my.x);<br />

temp_1.z = my.z - ((my._entity_z)/2);<br />

trace_mode = ignore_me + ignore_sprites + ignore_models + scan_texture;<br />

// my._BODENHÖHE beinhaltet die Entfernung zum Boden<br />

my._BODENHÖHE = trace(temp_1,temp);<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │33


my._floornormal auf die Normale des Bodens richten<br />

my._floornormal1_X = NORMAL.X;<br />

my._floornormal1_Y = NORMAL.Y;<br />

my._floornormal1_Z = NORMAL.Z;<br />

}<br />

Zuerst Überschreiben wir den temp Vektor mit Null, danach weisen wir dem Vektor die X-, Y- <strong>und</strong><br />

Z-Werte der Entity zu <strong>und</strong> verändern den Z-Wert auf 4000 Quants unter der Entity.<br />

Als nächstes schreiben wir die Koordinaten der Entity in den temp_1 Vektor <strong>und</strong> verändern den Z-<br />

Wert so das sich der Punkt genau an den Füßen der Entity befindet. Nun die Angabe des<br />

trace_mode. Hier ignorieren wir die my Entity, Sprites, Modelle <strong>und</strong> scannen die Textur unterhalb<br />

der Entity. Ich verwende hier bewusst nicht use_box da es beim scannen durch kleinere oder<br />

größere Entities als die Bo<strong>und</strong>ing Box bzw. die Hülle zu ungewünschten <strong>und</strong> fehlerhaften Effekten<br />

kommen kann. Das Ergebnis des Trace wird dann in den Skill my._Bodenhöhe geschrieben. Die<br />

letzten drei Zeilen beziehen sich noch auf Winkel des Bodens unterhalb der Entity, also die Normale<br />

des Bodens.<br />

3.5 Die Funktion "Abstand_Ecken()"<br />

function Abstand_Ecken()<br />

{<br />

//// Trace von Mitte nach unten ////<br />

vec_set(temp.x,my.x);<br />

temp.z = my.z - (my._entity_z)/2;<br />

trace_mode = ignore_me + ignore_passable + ignore_passents;<br />

my._dist_floorM = trace(temp.x,vector(temp.x,temp.y,temp.z-500));<br />

//// Trace von links nach unten ////<br />

vec_set(temp.x,vector(0,(my._entity_y/2),0));<br />

vec_rotate(temp.x,vector(my.pan,0,0));<br />

vec_add(temp.x,my.x);<br />

temp.z = my.z - (my.max_z - my.min_z)/2;<br />

trace_mode = ignore_me + ignore_passable + ignore_passents;<br />

my._dist_floorL = trace(temp.x,vector(temp.x,temp.y,temp.z-500));<br />

//// Trace von rechts nach unten ////<br />

vec_set(temp.x,vector(0,-(my._entity_y/2),0));<br />

vec_rotate(temp.x,vector(my.pan,0,0));<br />

vec_add(temp.x,my.x);<br />

temp.z = my.z - (my._entity_z)/2;<br />

trace_mode = ignore_me + ignore_passable + ignore_passents;<br />

my._dist_floorR = trace(temp.x,vector(temp.x,temp.y,temp.z-500));<br />

//// Trace von vorne nach unten ////<br />

vec_set(temp.x,vector((my._entity_x/2),0,0));<br />

vec_rotate(temp.x,vector(my.pan,0,0));<br />

vec_add(temp.x,my.x);<br />

temp.z = my.z - (my._entity_z)/2;<br />

trace_mode = ignore_me + ignore_passable + ignore_passents;<br />

my._dist_floorF = trace(temp.x,vector(temp.x,temp.y,temp.z-500));<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │34


}<br />

//// Trace von hinten nach unten ////<br />

vec_set(temp.x,vector(-(my._entity_x/2),0,0));<br />

vec_rotate(temp.x,vector(my.pan,0,0));<br />

vec_add(temp.x,my.x);<br />

temp.z = my.z - (my._entity_z)/2;<br />

trace_mode = ignore_me + ignore_passable + ignore_passents;<br />

my._dist_floorB = trace(temp.x,vector(temp.x,temp.y,temp.z-500));<br />

In dieser Funktion wird der Abstand von jeder Ecke der Entity zum Boden gemessen. Ich werde das<br />

ganze an Hand des Trace von links nach unten erklären. Die anderen Anweisungen basieren auf<br />

dem gleichen Prinzip. in der ersten Zeile speichern wir in die temp-Variable einen Vektor dessen X-<br />

<strong>und</strong> Z-Wert null sind <strong>und</strong> nur sein Y-Wert die Größe der halben Entity-Breite aufweist. Diesen<br />

Vektor drehen wir nun durch vec_rotate in Bezug auf den Pan-Wert der Entity. Nach der Drehung<br />

haben wir einen Vektor der 90 Grad nach Links steht mit der Länge der halben Entity. So, jetzt<br />

haben wir die Richtung des Vektors festgelegt. Was jetzt noch fehlt ist die genaue Lage, denn bis<br />

jetzt sitzt der Vektor noch auf dem Nullpunkt des WED. Um den Vektor in die richtige Endlage zu<br />

verschieben verwenden wir den Befehl vec_add. Wir addieren nun zu unserem Vektor den Vektor<br />

der Entity <strong>und</strong> schon sitzt der Punkt den wir haben wollten 90 Grad links neben unsere Entity. Nun<br />

noch den Z-Wert an den unteren Punkt der Entity verschieben <strong>und</strong> schon haben wir unseren ersten<br />

Tracepunkt festgelegt. Im trace_mode ignorieren wir diesmal wieder die my-Entity, Blocks die das<br />

passable-Flag gesetzt haben <strong>und</strong> Modelle <strong>und</strong> Sprites die auf passable gesetzt sind. Dann wird der<br />

Trace von unserem linken Punkt in eine Tiefe von 500 Quants ausgeführt <strong>und</strong> in den Skill<br />

my._dist_floorL übertragen. Das ganze führen wir von allen vier seitlichen Punkten <strong>und</strong> von der<br />

Mitte der Entity aus.<br />

3.6 Die Funktion "Schieflage()"<br />

function Schieflage()<br />

{<br />

temp = abs(my._dist_floorF - my._dist_floorB);<br />

if(temp 5<br />

&& my._dist_floorF > 5 && my._dist_floorB > 5)<br />

{<br />

return;<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │35


}<br />

}<br />

if (my._dist_floorL >= 5)<br />

{<br />

}<br />

temp = atan(my._dist_floorL/(my._entity_y/2));<br />

if(temp > abs(my.roll)) // Absolutberechnung da Roll negativ ist<br />

{<br />

}<br />

my.roll -= 1 * time;<br />

if (my._dist_floorR >= 5)<br />

{<br />

}<br />

temp = atan(my._dist_floorR/(my._entity_y/2));<br />

if(temp > my.roll)<br />

{<br />

}<br />

my.roll += 1 * time;<br />

if (my._dist_floorF >= 5)<br />

{<br />

}<br />

temp = atan(my._dist_floorF/(my._entity_x/2));<br />

if(temp > abs(my.tilt)) // Absolutberechnung da Tilt negativ ist<br />

{<br />

}<br />

my.tilt -= 1 * time;<br />

if (my._dist_floorB >= 5)<br />

{<br />

}<br />

temp = atan(my._dist_floorB/(my._entity_x/2));<br />

if(temp > my.tilt)<br />

{<br />

}<br />

my.tilt += 1 * time;<br />

Die Funktion Schieflage ist dafür da um Objekte, wenn sie über einen Abgr<strong>und</strong> geschoben werden<br />

<strong>und</strong> sich ihr Schwerpunkt verlagert, abrutschen zu lassen <strong>und</strong> sie nicht erst mit der<br />

Anziehungskraft in Berührung kommen wenn sie komplett darüber hinweg geschoben wurden.<br />

Als erstes die Berechnung der Deaktivierung der Schieflage <strong>und</strong> der Drift. Wenn der Bodenabstand<br />

zwischen den zwei Punkten der Entity, z.b. der Absolutwert der Differenz des äusseren linken <strong>und</strong><br />

rechten Punktes der Entity, kleiner als 1 Quant ist werden der Tilt-Winkel der Entity <strong>und</strong> der<br />

Driftfaktor auf Null gesetzt. Die gleiche Berechnung findet für den vorderen <strong>und</strong> den hinteren Punkt<br />

statt. Danach kommen zwei Einträge, die die Funktion beenden. Einmal die Abfrage vom mittleren<br />

Punkt zum Boden. Wenn der Abstand kleiner 2 Quants ist wird die Funktion beendet.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │36


Das ist klar denn in diesem Fall wäre der Schwerpunkt nicht über dem Abgr<strong>und</strong> <strong>und</strong> im zweiten Fall<br />

die Abfrage alles Punkte der Entity nach unten, denn da würde ja der freie Fall nach unten<br />

vorliegen was eine seitliche Drift auch beenden würde. Als nächste folgt wieder die Abfrage der<br />

einzelnen Aussenpunkte der Entity ob diese mehr als 5 Quants vom Boden entfernt sind <strong>und</strong> die<br />

darauffolgende Berechnung des Neigungswinkels mit Hilfe des Arcustangens.<br />

Mit temp = atan(my._dist_floorL/(my._entity_y/2)) berechnen wir den Neigungswinkel der Entity.<br />

Neigungswinkel = Arcustangens(Abstand zum Boden Links / Halbe Entity Breite). Dies ist also der<br />

Neigungswinkel, den die Entity erreichen muss wenn sie über einen Abgr<strong>und</strong> geschoben wird. Es<br />

folgt nun die Abfrage ob der Neigungswinkel grösser als der momentane Winkel der Entity ist.<br />

Sollte das der Fall sein wird zyklisch der Wert 1 zum Winkel der Entity dazu addiert. Die<br />

Berechnung der Neigungswinkel der anderen 4 Eckpunkte findet auf die selbe Art statt.<br />

3.7 Die Funktion "Anziehungskraft()"<br />

function Anziehungskraft()<br />

{<br />

}<br />

// in der Luft?<br />

if (my._dist_floorM > 5 && my._dist_floorL > 5 && my._dist_floorR > 5 &&<br />

my._dist_floorF > 5 && my._dist_floorB > 5)<br />

{<br />

}<br />

force.z = -5; // Schwerkraft<br />

friction = 0.1; // Luftreibung<br />

// Geschwindigkeit vertikal<br />

my._Bewegung_Vert = time*force.z + max(1-time*friction,0)*my._Bewegung_Vert;<br />

my._absoldis_Z = time * my._Bewegung_Vert;<br />

// Bis zu 5 Quant über dem Boden<br />

if (my._BODENHÖHE < 5 && my._BODENHÖHE > 0)<br />

{<br />

}<br />

my._Bewegung_Vert = 0;<br />

my._absoldis_Z = 0;<br />

// Eintauchen im Boden<br />

if (my._BODENHÖHE < 0 )<br />

{<br />

}<br />

force.z = -0.5 * my._BODENHÖHE; // Boden-Elastizität<br />

friction = 0.5; // Bodenreibung<br />

// Geschwindigkeit vertikal<br />

my._Bewegung_Vert = time*force.z + max(1-time*friction,0)*my._Bewegung_Vert;<br />

my._absoldis_Z = time * my._Bewegung_Vert;<br />

Kümmern wir uns nun um die Anziehungskraft, die ja bekanntlich auf jeden Körper wirkt. Als<br />

erstes Testen wir ob sich die Entity in der Luft befindet. Das überprüfen wir indem wir feststellen ob<br />

sich jeder Aussenpunkt mindestens 5 Quants über dem Boden befindet. Ist dies der Fall übergeben<br />

wir die Parameter der Schwerkraft <strong>und</strong> der Luftreibung <strong>und</strong> berechnen damit eine negative, da die<br />

Schwerkraft den Wert -5 hat, vertikale Bewegung.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │37


Die Berechnung, Strecke = Zeit * Beschleunigung, ergibt nun die absolute Z-Distanz der Entity. Im<br />

nachfolgenden Schritt, 5 Quant über dem Boden, gebe ich der Entity die Freiheit nicht genau auf<br />

dem Boden aufzusitzen sondern bis zu 5 Quant darüber zu bleiben. Der nächste Funktionsschritt<br />

bezieht sich auf das Eintauchen im Boden. Hier wird die Entity wieder aus dem Boden<br />

herausgezogen. Der Gr<strong>und</strong>wert der Geschwindigkeit ist hier wieder negativ (force.z = -0.5), was<br />

bedeuten würde das wir bei der späteren Berechnung nocheinmal eine negative vertikale<br />

Bewegung hätten. Das ganze bekommt jedoch einen positiven Wert da der force.z-Wert mit der<br />

Bodenhöhe multipliziert wird <strong>und</strong> die ist sobald wir im Boden eintauchen negativ. Da bekanntlich<br />

Minus * Minus = Plus ist werden wir im Laufe der nachfolgenden Berechnungen durch den jetzt<br />

positiven force.z-Wert wieder aus dem Boden herausgedrückt.<br />

3.8 Die Funktion "Drift()"<br />

function Drift()<br />

{<br />

//// Kippbereich der Objekte ////<br />

if (my._dist_floorM 0 || my._move_force > 0)<br />

{<br />

my._move_force = my._force * time + max(1-time*0.5,0)*my._move_force;<br />

my._force = 0;<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │38


}<br />

}<br />

Wenn Sie sich noch erinnern haben wir unseren Kraftfaktor my._force schon am Anfang des<br />

Tutorials kennen gelernt <strong>und</strong> zwar in der Berechnung:<br />

//// Schiebende Kraft ////<br />

my._force = ent_array1[ent_nr*10+6] * ent_array1[ent_nr*10+7];<br />

Dies ist die Kollisionskraft die uns von den Objekten die mit der Entity zusammen gestossen sind<br />

mitgegeben wurde. In der ersten If-Anweisung wird überprüft ob im Moment eine Driftbewegung<br />

ausgeführt wird. Sollte dies der Fall sein werden der Kraftfaktor <strong>und</strong> die daraus resultierende<br />

Geschwindigkeit auf 0 gesetzt. Die nächste If-Abfrage überprüft ob noch eine Kraft auf die Entity<br />

wirkt <strong>und</strong> führt bei einem positivem Ergebnis die Berechnung der schiebenden Kraft fort <strong>und</strong> setzt<br />

den Kraftfaktor auf 0. Das Rücksetzen des Kraftfaktors bewirkt, dass nach dem Erreichen der<br />

maximalen Geschwindigkeit die Entity wieder bis auf 0 abgebremst wird. Was in der Realität für<br />

Kraftbewegungen genauso zutrifft.<br />

3.10 Die Funktion "Bewegung()"<br />

function Bewegung()<br />

{<br />

{<br />

}<br />

ent_nr = my.ent_id;<br />

if(my._move_force > 0)<br />

my._absoldis_X = (cos(ent_array1[ent_nr*10+8])*(my._move_force/my._gewicht))*time;<br />

my._absoldis_Y = (sin(ent_array1[ent_nr*10+8])*(my._move_force/my._gewicht))*time;<br />

if(my._move_force


Bewegungsweg. Genau dieselbe Berechnung führen wir bei der Y-Verschiebung aus. In der<br />

nächsten If-Anweisung überprüfen wir ob noch eine Verschiebung der Entity durch die Drift oder<br />

die Kraftbewegung ausgeführt wird uns setzen bei keiner ausübenden Bewegung die X- <strong>und</strong> Y-<br />

Verschiebung auf 0. Gefolgt wird das Ganze von der Angabe des move_mode <strong>und</strong> der<br />

anschliessenden Bewegung der Entity mit den Absolutwerten.<br />

Ich hoffe ich konnte Ihnen einen kleinen Einblick in die Welt der einfachen Physik vermitteln. In<br />

einem der nächsten Tutorials werden ich noch die Bewegung auf schiefen Ebenen, Rotation, das<br />

Hochheben <strong>und</strong> Stapeln von Fässern oder Kisten basierend auf diesem Physik-Skript besprechen.<br />

Für Fragen <strong>und</strong> Anregungen stehe ich Ihnen gerne unter meiner E-Mail Adr.<br />

aras_game@chefmail.de<br />

MFG<br />

ARAS14<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │40


Zum Kugeln<br />

oder: Der einfache weg zum nahtlosen UV-Gitter<br />

Willkommen zu meinem ersten Tutorial über Mapping <strong>und</strong> 3d-Modelle. Auf zwei Seiten werden Sie<br />

lernen, wie einfach es ist, eines der schwersten Objekte im Raum auf eine Fläche abzuwickeln <strong>und</strong><br />

mit einer Textur zu versehen.<br />

Vorher sollte Ihnen aber klar sein, dass diese, wie jede andere Methode auch, ihre Probleme hat<br />

<strong>und</strong> keineswegs der ultimative Weg zum Glück ist. So eignet sich die Methode gut für Nebel-<br />

Spheres oder Asteroiden, weniger aber für Himmelskörper wie Globen oder Planeten, bei denen es<br />

auf die möglichst verzerrungsfreie Darstellung der Textur ankommt. Hier bleibt Ihnen wohl<br />

vorläufig nichts Anderes übrig, als Ihre Texturen von Hand einzupassen.<br />

Wir beginnen zunächst mit einem Ausgangsbild.<br />

Es ist weder kachelbar, noch für Kugeln angepasst. Für die Umwandlung des Bildes benötigen wir<br />

zwei kostenlose Plugins für Grafikprogramme wie beispielsweise Photoshop oder Paint Shop Pro,<br />

aber auch kostenlose Programme werden unterstützt.<br />

Besuchen Sie http://www.richardrosenman.com/software/downloads/, hier finden Sie auch die<br />

volle Liste der unterstützen Programme. Die benötigten Plugins heißen „Spherical Mapping<br />

Corrector" <strong>und</strong> „Tiler", laden Sie sie herunter <strong>und</strong> entpacken Sie die Zip-Archive in den Plugin-<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │41


Ordner Ihres Malprogrammes.<br />

1) Laden Sie das Bild in Ihr Grafikprogramm.<br />

2) Führen Sie das Plugin „Spherical Mapping Corrector" aus.<br />

3) Nutzen Sie das Plugin „Tiler", um die rechten <strong>und</strong> linken Kanten nahtlos ineinander über gehen<br />

zu lassen, Sie können die Werte des Screenshots als Referenz nehmen:<br />

4) Wickeln Sie Ihre Kugel mit einem Sphere-Mapping- Algorithmus in Ihrem 3d-Programm aus, so<br />

dass das Gitter wie im folgenden Bild aussieht:<br />

Sowohl Cinema4d <strong>und</strong> 3ds Max, als auch kostenlose bzw. kostengünstige Tools wie Wings3d,<br />

UltimateUnwrap/LithUnwrap oder Blender werden mit einem Knopfdruck damit fertig. Texturieren<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │42


Sie Ihre Kugel mit der soeben erstellten Map et voilà. Keine Pole, keine Nähte.<br />

Ein Wermutstropfen bleibt jedoch, streckenweise ist die Textur leicht verzerrt, somit sollte Ihre Map<br />

eine vernünftige Auflösung besitzen <strong>und</strong> keine Beschriftungen oder Ähnliches beinhalten.<br />

Felix Caffier<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │43


Jetzt gibt's auf die Ohren! So<strong>und</strong>effekte Teil 3<br />

Herzlich willkommen zum dritten Teil des So<strong>und</strong>effekt Tutorials.<br />

Heute werden wir einen verwendbaren So<strong>und</strong> designen, einen Schuss, um genau zu sein. Dieser<br />

hier passt am ehesten zu einer Maschinenpistole oder ähnlichem. Sie werden erfahren wie Sie den<br />

So<strong>und</strong> erstellen, ihn bearbeiten <strong>und</strong> in die Engine einfügen. Und Sie werden vielleicht überrascht<br />

sein, wie simpel die Gr<strong>und</strong>sätze mal wieder sind.<br />

Zusätzlich gibt es einige Tipps <strong>und</strong> Tricks zur Einbindung von So<strong>und</strong>s in <strong>Gamestudio</strong>.<br />

Um dieses Tutorial durcharbeiten zu können benötigen Sie den „So<strong>und</strong>forum Synth V 1.0", den Sie<br />

hier erhalten:<br />

http://www1.keyboards.de/so<strong>und</strong>forum.htm#dersynthesizer<br />

WARNUNG: Softwaresynthesizer können jeden möglichen <strong>und</strong> unmöglichen Ton<br />

erzeugen. Auch solche, die jenseits der Leistungsfähigkeit Ihrer Lautsprecher liegen!<br />

Seien Sie vorsichtig, beginnen Sie mit niedrigen Lautstärken <strong>und</strong> verwenden Sie bitte<br />

keine Kopfhörer. Der Schalldruck kann ungeahnte Ausmaße annehmen <strong>und</strong> zu<br />

Hörschäden führen! Ich übernehme keine Verantwortung für materielle <strong>und</strong> / oder<br />

körperliche Schäden die aus der Benutzung dieses Tutorials resultieren.<br />

Starten Sie den So<strong>und</strong>forum Synth <strong>und</strong> wählen Sie die Voreinstellung „Basic Noise".<br />

Wenn Sie einige Tasten drücken, können Sie in der Tat ein Rauschen hören. Nun wollen wir daraus<br />

einen Schuss generieren.<br />

Um Sie nicht zu sehr zu verwirren, stellen wir erstmal alle Hüllkurvenregler auf null, ausgenommen<br />

die „Decay" Regler, die kommen auf 20.<br />

Schauen Sie sich das Bild dazu an:<br />

In der Filter Sektion stellen Sie bitte „Cutoff" auf 70 ein <strong>und</strong> „Env" auf 40. Es werden also nur<br />

tiefere Frequenzen durchgelassen, wobei die Hüllkurve des Filters auch etwas Einfluss hat.<br />

„K-Track" stellen Sie bitte auf Null, um unerwünschte Tonhöheneinflüsse durch das Keyboard<br />

auszuschließen.<br />

Nun müssen Sie etwas lauter machen, entweder am „Level" Regler des Synth oder an Ihren Boxen.<br />

Der Gr<strong>und</strong> hierfür: Der Filter lässt nur noch tiefe Frequenzen durch. Da diese im hellen Rauschen<br />

nur sehr leise vorhanden sind, müssen<br />

Sie sie verstärken.<br />

Was da so ein wenig nach klopfen auf Holz klingt, ist Ihr Ausgangsmaterial für den Schuss!<br />

Nun wird es Zeit für eine bittere Pille: Der So<strong>und</strong>forum Synth kann keine So<strong>und</strong>s exportieren.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │44


Wenn sie über die So<strong>und</strong>karte abgenommen werden, klingen sie sehr verrauscht.<br />

Um Ihnen dennoch die Möglichkeit zu geben, den So<strong>und</strong> fertig zu machen, habe ich mit Reaktor4<br />

den gleichen So<strong>und</strong> erstellt <strong>und</strong> hochgeladen. Sie finden sämtliche Dateien hier:<br />

http://home.arcor.de/braindamaged/so<strong>und</strong>tut3.zip<br />

Zusätzlich brauchen Sie noch das folgende Programm: http://www.audacity.de<br />

Dieses Programm dient zur Bearbeitung von Audiodaten. Genau daß, was Sie brauchen. Und<br />

obendrein kostet es keinen Cent!<br />

Stellen Sie sicher, daß ein Ogg-Codec auf ihrem System installiert ist.<br />

Nach dem starten von Audacity <strong>und</strong> öffnen der Datei „shot1.ogg" bietet sich Ihnen folgendes Bild:<br />

Der So<strong>und</strong> ist immer noch recht leise <strong>und</strong> liegt in Stereo vor. Das ist nicht unbedingt gut. Für einen<br />

Schuß lohnt es sich nicht, auf Stereo zu pochen. Mono reicht hier völlig aus.<br />

Klicken Sie hierzu links neben der oberen „Tonspur" auf den Pfeil bei „shot1". Nun öffnet sich ein<br />

kleines Kontextmenü, in dem Sie „Stereotonspur aufteilen" wählen.<br />

Mit einem Klick auf das Kreuz der zweiten Tonspur löschen Sie diese. Nun ist nur noch eine übrig,<br />

die Sie über das Kontextmenü auf „Mono" setzen können.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │45


Wählen Sie „Bearbeiten" --> „Auswählen" --> „Alles". Dies ist nötig, um den So<strong>und</strong> lauter zu<br />

machen.<br />

Wählen Sie nun „Effekt" --> „Verstärken":<br />

Klicken Sie auf „Ok". Nun ist der So<strong>und</strong> wesentlich lauter. Wählen Sie mit der Maus den stillen<br />

Bereich vor dem So<strong>und</strong> aus <strong>und</strong> löschen Sie ihn mit „Bearbeiten" --> „Auswahl löschen". Mit der<br />

stillen Stelle nach dem So<strong>und</strong> verfahren Sie genauso. Nun ist der So<strong>und</strong> auch schön handlich:<br />

Leider klingt er noch nicht überzeugend. Um ihm etwas mehr punch zu geben, schauen Sie mal<br />

unter „Effekt" --> „Tonhöhe (Pitch) ändern":<br />

Wählen Sie einen Wert von 40%. Wenn Sie damit schon zufrieden sind, können Sie den So<strong>und</strong> als<br />

Ogg oder Wav exportieren. Ich rate Ihnen zu Ogg - sie sind wesentlich kleiner <strong>und</strong> kosten keine<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │46


Lizenzgebühren wie mp3. Das dazu ein extra Codec nötig ist, kann man verschmerzen.<br />

Spielen wir ein wenig mit dem Kompressor herum:<br />

Markieren Sie alles wenn dies nicht schon der Fall ist. Gehen Sie auf "Effekte" --> "Kompressor".<br />

Es ist wichtig daß Sie die Ansprechzeit auf 0,1 Sek<strong>und</strong>en stellen. Ansonsten spricht der Effekt zu<br />

spät an.<br />

Lassen Sie sich nicht täuschen, sollten Sie kaum einen Unterschied hören beim experimentieren<br />

mit diesem Effekt.<br />

In der Wiederholung als MG-So<strong>und</strong> wirken sich auch kleine Änderungen aus.<br />

Starten Sie „shot.exe" <strong>und</strong> schauen Sie sich die wdl Datei an, um einen Eindruck davon zu<br />

bekommen, wie man den So<strong>und</strong> einsetzen könnte. Vor allem mit der „snd_tune" Anweisung kann<br />

man einiges anstellen.<br />

Ich hoffe, es hat Ihnen Spass gemacht. Natürlich kann es dieser So<strong>und</strong> nicht mit aktuellen So<strong>und</strong>s<br />

aus der Spielebranche aufnehmen. Hierfür ist der So<strong>und</strong>forum Synth nicht flexibel genug. Aber<br />

lassen Sie sich gesagt sein: Auch die Profis kochen nur mit Wasser. ;-)<br />

Letztlich wird nahezu jede Explosion <strong>und</strong> jeder Schuss aus Rauschen generiert. Ob es von einem<br />

Oszillator produziert wurde oder ursprünglich ein ganz anderes Geräusch (im wahrsten Sinne) war,<br />

ist nur eine Möglichkeit der Variation.<br />

Das nächste Mal werden wir uns mit der Verfremdung <strong>und</strong> Veränderung von bereits vorhandenen<br />

So<strong>und</strong>s mit Audacity beschäftigen. Außerdem lernen Sie, wie Sie mit vertretbarem Aufwand gute<br />

Aufnahmen erstellen können.<br />

Ich wünsche Ihnen viel Spass bis dahin, Torsten Fock<br />

www.vulkanware.de<br />

Tipps <strong>und</strong> Tricks zur Einbindung<br />

snd_tune(handle, Volume, Freq, balance);<br />

Diese Anweisung hilft Ihnen, etwas Zufall in die Sache zu bringen oder Motorenso<strong>und</strong>s zu steuern.<br />

Schauen Sie sich das folgende, kurze Script an:<br />

function play_crossfire<br />

{<br />

var sndhandle;<br />

sndhandle = snd_play(crossfire_snd, 100, 0);<br />

temp = random(20)+90;<br />

snd_tune(sndhandle, temp, temp, 0);<br />

}<br />

Hier wird direkt nachdem der So<strong>und</strong> angestossen wurde seine Frequenz (<strong>und</strong> die<br />

Abspielgeschwindigkeit!) sowie die Lautstärke zufällig geändert. Dies eignet sich sehr gut für<br />

Kreuzfeuer, Querschläger, Explosionen u.s.w.<br />

Gehso<strong>und</strong>s zur Animation synchronisieren:<br />

-skill1 muß auf 1 gesetzt werden, wenn die Entity läuft.<br />

-skill2 ist in diesem Beispiel der animationszähler der Figur 0...100%.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │47


function char_so<strong>und</strong>s<br />

{<br />

while(me)<br />

{<br />

}<br />

if(my.skill1 == 1) // ich laufe<br />

{<br />

}<br />

snd_play(walk_1_snd, 100, 0);<br />

while(my.skill2 < 50){wait(1);}<br />

snd_play(walk_1_snd, 100, 0);<br />

while(my.skill2 > 0){wait(1);}<br />

wait(1);<br />

}<br />

Motorengeräusche:<br />

freq ist eine Variable, die von der Geschwindigkeit des Wagens beeinflußt wird.<br />

Wenn Sie es realer haben wollen, müssen Sie in ein aufwändigeres Script anfertigen, daß sich mit<br />

der "Drehzahl" der Reifen <strong>und</strong> dem Zustand der Gangschaltung beschäftigt.<br />

function tune_so<strong>und</strong><br />

{<br />

var so<strong>und</strong>handle;<br />

so<strong>und</strong>handle = snd_loop(engine_snd, 100, 0) // oder ent_playloop benutzen, je nach Bedarf<br />

while(me)<br />

{<br />

}<br />

snd_tune(so<strong>und</strong>handle, 0, freq, 0);<br />

wait(1 ;<br />

}<br />

var doppler_factor<br />

Kennen Sie die Variable "doppler_factor"?<br />

Sie dient dazu den bekannten Doppler-Effekt zu steuern. Je nach Wert (0-10) ist der Effekt weniger<br />

oder mehr ausgeprägt.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │48


Versionskontrolle mit Subversion<br />

mit Beispielen anhand einer <strong>3D</strong> <strong>Gamestudio</strong> Demo-Applikation von Christian Behrenberg<br />

Vorwort<br />

Dieser Artikel sollte eigentlich kürzer werden als er tatsächlich wurde. Aber ich habe schnell<br />

gesehen, dass eine Auflistung aller basics r<strong>und</strong> um Subversion <strong>und</strong> eine knappe Erklärung, was<br />

man da macht, einfach nicht genug ist. Ich habe eine Einführung in die Revisionskontrolle<br />

eingefügt <strong>und</strong> anhand eines trivialen Beispiels mit dem <strong>3D</strong>GS das ganze versucht, anschaulich zu<br />

machen. Literaturangaben <strong>und</strong> Quellen stehen am Ende des Artikels. Ich setze meine Hoffnungen<br />

darin, das wenigstens ein paar Leute von diesem Artikel profitieren. Viele Menschen, die sich mal<br />

kurz mit der Revisionskontrolle auseinandersetzen, sagen, dass es zuviel Aufwand sei. Vor allem<br />

bei kleineren Projekten <strong>und</strong> wenn man alleine arbeiten würde. Ich sehe das nicht so, weil mir das<br />

SVN eine Menge Sicherheit <strong>und</strong> Möglichkeiten bietet <strong>und</strong> mich durchdachter meine Projekte planen<br />

lässt. In der professionellen Softwareentwicklung ist eine RC (= Revision Control) unabdingbar, weil<br />

dadurch die Entwicklungszeit dramatisch verkürzt wird <strong>und</strong> dem Projekt eine nötige Stabilität <strong>und</strong><br />

Flexibilität verliehen wird. Viele kleine bis große Projekte, die unglaubliches Potential haben,<br />

scheitern genau an diesem Punkt. Wissen <strong>und</strong> Erfahrung auf dem Gebiet des Projektmanagements<br />

<strong>und</strong> den entsprechenden Tools dafür ist für die meisten ein gigantischer Schritt auf dem Weg vom<br />

eher „dreckigen" oder „schluderigen" Weg der Projektführung (oder von Softwareentwicklung<br />

allgemein) zu einem erfolgreicheren Weg - der zum gewünschten Ziel führt. Zwar gehört dazu eine<br />

Menge eigener Einsatz (<strong>und</strong> vor allem der Wille!), aber wenn man weiß, was man machen kann,<br />

dann ist einem auch schon geholfen - vorrausgesetzt, man wendet es auch an ;) RC ist ein<br />

Standard in der Industrie <strong>und</strong> je früher man damit anfängt, desto besser ist das für sich selbst, für<br />

das Team, aber am meisten für das Projekt. Deshalb hoffe ich, dass der Leser das Potenzial sieht<br />

<strong>und</strong> nicht vor dem Artikel kapituliert - die investierte Zeit wird sich rentieren, ganz sicher.<br />

Einführung<br />

Typische Fehler in der Softwareentwicklung<br />

Wer mit Spieleprojekten vertraut ist, bei denen sehr viel Quelltext <strong>und</strong> sehr viel Content produziert<br />

wird, kennt so einige Situationen, in denen man fast verzweifelt, weil durch einen unglücklichen<br />

Umstand das komplette Projekt auf der Kippe steht. Vor allem aber passieren solche Vorfälle auch<br />

dann, wenn mehrere Leute an einem Projekt arbeiten. Hier nun einige Fälle, die Sie sicherlich<br />

schon einmal durchlebt haben:<br />

✗ Irgendwas im code funktioniert nicht, man sucht den Fehler, man baut zahlreiche Fixes ein <strong>und</strong><br />

am Ende bricht das ganze Programm ein. Nach etlichen St<strong>und</strong>en oder Tagen Arbeitszeit hat man<br />

dann mühsam durch teilweise lückenhafte Backups den code wiederhergestellt <strong>und</strong> vielleicht<br />

funktioniert das Programm dann wieder - oder eben nicht. Das Projekt ist zum Scheitern verurteilt.<br />

✗ Mehrere Programmierer haben an verschiedenen Spielmodulen gearbeitet <strong>und</strong> wollen nun alles<br />

zusammenfügen - ein heilloses Chaos. Denn wie es aussieht, hat jeder Programmierer irgendwo<br />

anders Modifikationen vorgenommen <strong>und</strong> man kann die neuen Sachen nicht einfach so<br />

zusammenfügen. Es geht viel Zeit verloren, nur um die Sachen lauffähig ins Spiel zu integrieren -<br />

sofern jemand dazu in der Lage ist, das überhaupt zu bewerkstelligen.<br />

✗ Es arbeiten mehrere Leute an einem Projekt <strong>und</strong> alle sind über das Internet verstreut. Jeder will<br />

die aktuelle Version haben, aber es gibt nur den Teamleiter, der immer den aktuellen Stand hat <strong>und</strong><br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │49


mal alle paar Wochen eine Version rausgibt, weil das immer so kompliziert ist mit dem<br />

Zusammenpacken aller Daten. Ist er verhindert oder krank, kann das Projekt nicht fortgeführt<br />

werden - alle müssen warten.<br />

✗ Man kann nicht verfolgen, wer was wann gemacht hat. Wenn man dann beim Debuggen nach<br />

Fehlern sucht <strong>und</strong> genau wissen muss, wann wo welche Änderungen weshalb von wem gemacht<br />

worden sind - dann ist man meistens aufgeschmissen - weil es eben niemand weiß!<br />

✗ Etc.pp. - typische Softwarefallen halt.<br />

Solche Fälle passieren zu Hauf während einer Softwareentwicklung. In solchen Fällen leidet das<br />

Team - <strong>und</strong> die Organisation bzw. die Projektverwaltung nimmt immer mehr Zeit in Anspruch als<br />

notwendig. Mit einer sogenannten Versionskontrolle sind aber alle diese Probleme gelöst.<br />

Was ist eine „Versionsverwaltung" <strong>und</strong> was hat das mit<br />

Spieleentwicklung zutun?<br />

Versionsverwaltung<br />

Unter einer Versionsverwaltung versteht man ein System, welches typischerweise in der<br />

Softwareentwicklung zur Versionierung <strong>und</strong> um den gemeinsamen Zugriff auf Quelltexte zu<br />

kontrollieren, eingesetzt wird. Das System hält dabei immer die Änderung der Datei(en) fest, wer<br />

sie bearbeitet hat <strong>und</strong> wann er das getan hat. Wogegen binäre Dateien (Bilder, Musik, etc.) immer<br />

komplett gespeichert werden, werden bei Textdateien (code, Dokumentation, etc.) immer nur die<br />

Unterschiede gespeichert, sodass man sich auch die Unterschiede anschauen kann - insbesondere<br />

dann nützlich wenn man schauen will, was man selbst oder jemand anderes im code eigentlich so<br />

verändert hat. Das ist sehr nützlich bei der Entwicklung von Programmen, Dokumentationen <strong>und</strong><br />

Veröffentlichungen, insbesondere auch dann, wenn mehrere Entwickler daran beteiligt sind.<br />

Dabei wird sichergestellt, dass jeder Benutzer mit dem aktuellen Stand arbeitet oder auf Wunsch<br />

auf die archivierten Stände zugreifen kann. Dadurch ist eine Versionsverwaltung nicht nur für<br />

professionelle Entwickler in großen Teams, sondern auch für einzelne Entwickler interessant. Es<br />

kann jederzeit eine ältere Version aufgerufen werden, falls eine Änderung nicht funktioniert <strong>und</strong><br />

man sich nicht mehr sicher ist, was nun alles geändert wurde - somit sind solche GAUs irrelevant,<br />

weil man jederzeit auf die letzte funktionierende Fassung zurückgreifen kann. Dadurch, dass man<br />

immer funktionierende Versionen in das System einfügt <strong>und</strong> anderen zugänglich macht, ist damit<br />

schlussfolglich auch immer sichergestellt, dass jeder Benutzer Zugriff auf die aktuell voll funktions-<br />

<strong>und</strong> lauffähige Version der Software hat.<br />

Anwendung bei Spieleprojekten<br />

Spieleentwicklungen sind technisch gesehen die anspruchsvollsten Softwareproduktionen<br />

überhaupt: man realisiert mehr oder weniger anspruchsvolle Softwarelösungen für die<br />

verschiedensten Anforderungen, die es in der modernen Softwareentwicklung gibt. Dazu kommt,<br />

dass heutezutage der Anteil des Grafik-contents immer beträchtlicher wird. Kein W<strong>und</strong>er, dass an<br />

kommerziellen Spielen Dutzende Leute arbeiten, zum Teil in verschiedene Teams unterteilt <strong>und</strong> in<br />

diesen Teams Untergruppen mit verschiedenen Aufgabenbereichen. Auch kleine, unabhängige<br />

Produktionen beschäftigen mittlerweile ein Gruppe von Entwicklern, die zusammen an einem Spiel<br />

arbeiten. Solche Probleme, wie sie oben geschildert sind, wären wie ein halber Todesstoß für das<br />

Projekt. Viele Amateur-Entwickler schließen sich nun auch über das Internet zusammen, um<br />

gemeinsam an kleinen Spielen zu basteln.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │50


Die meisten Projekte scheitern allerdings, was statistisch gesehen durchaus plausibel ist: fehlende<br />

Erfahrung, keine Geldmittel für Tools <strong>und</strong> eine <strong>und</strong>urchdachte, fast chaotische Organisation<br />

kristalliert sich schon nach kurzer Zeit heraus. Man kann davon ausgehen, dass über 75% dieser<br />

„Projekte" den Bach runtergehen. Das liegt aber auch daran, das meistens nur eine, maximal zwei<br />

Personen Zugang zum source-code des Spiels haben. Das ist dann auch schon meistens der Haken,<br />

weil diese Person selber entwickelt <strong>und</strong> meistens keine Ahnung davon hat, was sie eigentlich zutun<br />

hat. Es entsteht kein echter Workflow, weil jeder nur über diese eine Person Zugang hat.<br />

Ein Revision Control System, z.B. „Subversion", löst aber alle diese Probleme (s.o.). Nun können<br />

alle Leute gleichzeitig an dem Spiel arbeiten, jederzeit eine aktuelle Version herunterladen, Zugriff<br />

auf alle Änderungen haben, zu unterschiedlichen Zeiten daran arbeiten <strong>und</strong> live neue<br />

Dateiversionen einspielen, wenn man zeitgleich zeitkritisch an einem bugfix arbeitet, etc. Grafiker<br />

können dann auch ihre Dateien unter Revision Control setzen, Änderungen durchführen <strong>und</strong> wenn<br />

Sie später feststellen, dass die aktuellen Änderung im Spiel schlecht aussehen, das ändern.<br />

Komplizierte Backupsysteme sind somit nicht mehr nötig <strong>und</strong> die Entwicklung kann viel<br />

dynamischer <strong>und</strong> viel sicherer stattfinden.<br />

Subversion <strong>und</strong> andere Tools<br />

Es gibt eine Reihe von Revision Control Software auf dem Markt, sowohl kommerzielle als auch<br />

kostenlose. Subversion ist ein Open Source Projekt <strong>und</strong> der inoffizielle Nachfolger von CVS. Es gibt<br />

auch einige Tools, wie z.B AlienBrain, die speziell auf content-reiche Projekte, wie eben<br />

Spieleproduktionen, ausgelegt sind. Allerdings kosten diese auch z.T. viel Geld. Es gibt eine<br />

Windows shell-extension für Subversion, „Tortoise SVN" genannt, welches in diesem Artikel<br />

vorgestellt <strong>und</strong> benutzt wird. Im Folgenden wird Subversion mit SVN abgekürzt.<br />

Download <strong>und</strong> Installation von Subversion auf einem Einzelplatz PC<br />

✔ Besuchen Sie die Internetseite http://tortoisesvn.tigris.org/<br />

✔ Klicken Sie auf den Bereich „Download" (http://tortoisesvn.net/downloads)<br />

✔ Es werden 32-bit <strong>und</strong> 64-bit Versionen vom SVN angeboten. Klicken Sie auf die entsprechende<br />

Installerfile. Sie werden automatisch auf die entsprechende Source Forge Seite re-directed, wo Sie<br />

automatisch die Installationsdatei herunterladen.<br />

✔ Wenn Sie die Datei herunterladen haben, starten Sie sie <strong>und</strong> folgen Sie den<br />

Bildschirmanweisungen. Am Ende haben Sie das SVN <strong>und</strong> die Tortoise shell erfolgreich installiert.<br />

Eventuell müssen Sie den PC neustarten.<br />

Wie funktioniert das SVN?<br />

Eine kleine Geschichte<br />

Das SVN benutzt ein sogenanntes Repository. Diese Repository logged alle geänderten Dateien,<br />

Modifikationen im SVN, wer was wann gemacht hat. Wenn Sie einen neuen Ordner erstellen <strong>und</strong><br />

dort die aktuellste Version der unter RC gestellten Dateien haben wollen, so ziehen Sie eine<br />

sogenannte Working Copy („WC") - dies impliziert, dass jede WC lauffähig <strong>und</strong> funktionabel ist.<br />

Stellen Sie sich nun vor, Sie sind Programmierer <strong>und</strong> wollen eine Änderung vornehmen, z.B. die<br />

Gegner in Ihrem Spiel intelligenter machen. Sie ändern die Dateien in der WC <strong>und</strong> wollen diese<br />

geänderten Dateien nun in das Repository hochladen (damit die anderen Entwickler des Spiels<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │51


auch Zugriff auf den geändert Code haben). Den Upload ins Repository nennt man „Commit". Das<br />

heißt, dass Sie ihre Änderungen dem System mitteilen. Es wird nicht nur ihre User-ID gespeichert,<br />

sondern auch wann sie commited haben <strong>und</strong> welche Dateien sie modifiziert haben (<strong>und</strong> wie). Sie<br />

können optional auch noch eine change-log Message einbauen, die einen Kurzüberblick gibt.<br />

Nehmen wir an, ihr Programmierkollege im Büro nebenan hat diesselbe Version der WC vm<br />

Firmenserver gezogen <strong>und</strong> hat nun auch im Gegnerskript was an der Animation geändert. Sie<br />

haben also die beiden gleichen Dateien bearbeitet, sie haben aber schon comitted. Was passiert<br />

nun, wenn ihr Kollege comitten will? Das SVN bemerkt diesen Conflict <strong>und</strong> teilt diese ihrem<br />

Kollegen mit. Er kann sich nun die Unterschiede von seiner zur neuen Version der Datei anschauen<br />

<strong>und</strong> entscheiden, welche Codeteile von ihm übernommen werden, welche von Ihnen entfernt<br />

werden oder welche Teile gemergedt (zusammengefügt) werden. Nach dem Commit von ihrem<br />

Kollegen (er teilt es Ihnen über einen Messenger mit), sind sie neugierig auf die neuen<br />

Animationen im Zusammespiel mit ihrer KI. Sie machen also ein Update <strong>und</strong> dabei werden die<br />

Änderungen (Changes) direkt in ihrer WC geändert. Sie freuen sich: es sieht gut aus <strong>und</strong> die<br />

Zusammenarbeit fand gleichzeitig ohne Probleme statt.<br />

Anmerkungen zum Multi-User System<br />

Im Folgenden wird Ihnen nun erklärt, wie sie selbst eine SVN RC auf ihrem Einzelplatz PC<br />

einrichten <strong>und</strong> bedienen.<br />

Wichtig: wenn Sie Subversion auf einem Server benutzen wollen, den Sie von überall aus<br />

erreichen wollen, so brauchen Sie einen Root-Server Account bei Ihrem Hoster oder einen eigene<br />

Server, weil Sie den Server entsprechend konfigurieren müssen. Daher wird in diesem Artikel nur<br />

auf die Einzelplatzbenutzung eingegangen. Weitere Details zur Benutzung des SVNs als Server<br />

finden Sie im OpenBook „Versioncontrol with Subversion" (http://svnbook.red-bean.com/).<br />

Wenn Sie im Netzwerk arbeiten, so können Sie Subversion auf einem Rechner einrichten <strong>und</strong> das<br />

Repository als Netzlaufwerk verbinden. Im Folgenden werden auch Situationen aus einem Multi-<br />

User Betrieb geschildert, allerdings trifft dies auch zu, wenn Sie alleine mit dem SVN arbeiten - es<br />

dient nur der Veranschaulichung. Damit Sie gleich die Benutzung im Zusammenhang mit dem<br />

<strong>3D</strong>GS lernen, wird dies an einem Miniprojekt erläutert.<br />

Der normale Arbeitsablauf mit dem SVN - Features <strong>und</strong> Erklärungen<br />

Subversion hat viele Features, Optionen <strong>und</strong> viele Kleinigkeiten <strong>und</strong> Extras - aber im täglichen<br />

Betrieb werden Sie nur ein paar benutzen. Der typische Arbeitsablauf (oder -zyklus) mit dem SVN<br />

sieht so aus:<br />

• man updatet seine eigene Working Copy<br />

• SVN update<br />

• man macht seine Änderungen (neuer code, bugfixes, neue Grafiken, etc.)<br />

• SVN add (neue Dateien hinzufügen)<br />

• SVN delete (Dateien löschen)<br />

• man schaut sich seine Änderungen an<br />

• SVN status (Dateistatus (s.o.) abfragen<br />

• SVN diff (Unterschiede zur letzten oder einer anderen Revision angucken)<br />

• SVN revert (die geänderte Datei auf den letzten WC Stand bringen oder auf den Stand einer<br />

anderen Revision)<br />

• man merged seine Änderungen mit den Änderungen der anderen Entwickler<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │52


• SVN update (s.o.)<br />

• SVN resolved (bei Konflikten)<br />

• man commited seine Änderungen ins SVN Repository<br />

• SVN commit<br />

Das Repository<br />

Bevor wir nun das Spieleprojekt überhaupt starten, erzeugen wir uns ein leeres Repository,<br />

welches gleich die ersten Daten von der ersten unter RC gestellten Version unserer Demo enthalten<br />

wird.<br />

1. Erstellen Sie in Ihrem Projekte-Verzeichnis (wenn Sie denn eins haben) einen Ordner für unsere<br />

SVN Demo. Ich habe ihn „SVNDemo" genannt. Erstellen Sie dort ein Verzeichnis, welches das SVN<br />

Repository beherbergt. In meinem Beispiel lautet der Ordner „SVNDEMO_REPO".<br />

2. Klicken Sie mit der rechten Maustaste auf diesen Ordner. Sie sehen 2 neue Icons im<br />

Kontextmenü: „SVN Checkout" <strong>und</strong> „TortoiseSVN". Zeigen Sie auf „TortoiseSVN" <strong>und</strong> klicken Sie auf<br />

„Create repository here...".<br />

3. Im folgenden Dialog werden Sie gefragt, welches Dateisystem Sie wählen wollen. Da uns das<br />

egal ist, bleiben wir beim „Native filesystem (FSFS)". Das Erstellen eines SVN Repository in diesem<br />

Ordner wird dann bestätigt.<br />

Glückwunsch! Ihr Repository ist nun eingerichtet. Bitte ändern Sie NICHTS in diesem Ordner, das<br />

wird später das SVN für Sie übernehmen. Bevor wir die erste Spielversion comitten, müssen wir<br />

erst eine erste Version überhaupt erstellen:<br />

1. Erstellen Sie im Ordner „SVNDemo" einen temporären Ordner „temp"<br />

2. Starten Sie den WED <strong>und</strong> erzeugen Sie einen hollow-cube <strong>und</strong> weisen Sie ihm die Standard-<br />

Textur zu. Speichern Sie die Szene als room.wmp in diesem temp-Ordner <strong>und</strong> kompilieren Sie die<br />

WMB Datei.<br />

3. Erzeugen Sie eine .wdl Datei in diesem Ordner <strong>und</strong> nennen diese „main.wdl". Weisen Sie diese<br />

WDL Datei dem Level zu. Schreiben Sie folgenden code in die WDL Datei:<br />

function main ()<br />

{<br />

level_load("room.wmb");<br />

wait(3);<br />

while (1)<br />

{<br />

}<br />

camera.pan += 5 * time_step;<br />

wait(1);<br />

}<br />

Wenn Sie das Level über den WED starten, dreht sich die Kamera andauernd im Kreis.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │53


Die soll unsere erste Version des Spiels sein. Ihnen werden alle Features vom SVN anhand dieses<br />

Beispiels erklärt. Nun wollen wir aber diese Version in das Repository als erste Version importieren:<br />

1. Klicken Sie mit der rechten Maustaste auf den Ordner „temp".<br />

2. Gehen Sie auf „TortoiseSVN \ Import...". Im folgenden Import-Fenster werden Sie zunächst dazu<br />

aufgefordert die URL des Repositories anzugeben. Da es sich bei Ihnen auf der Festplatte befindet,<br />

klicken Sie auf „..." <strong>und</strong> klicken Sich durch ihr System bis zu diesem Ordner. Markieren Sie ihn <strong>und</strong><br />

klicken Sie auf OK. Im Textfeld müsste dann z.B. sowas wie<br />

„file:///I:/Projects/SVNDemo/SVNDEMO_REPO" stehen.<br />

3. Bei jedem Import können Sie eine Import-Message anlegen. Geben Sie beispielhaft „SVN-Demo<br />

Repository eröffnet!" an.<br />

4. Klicken Sie OK. Sie sehen dann, wie das SVN die Dateien in das Repository addet.<br />

5. Nun löschen Sie den Ordner „temp". Er wird nicht mehr benötigt.<br />

6. Erzeugen Sie nun den Ordner, unter dem Sie das unter RC stehende Spiel finden. Nennen Sie<br />

ihn z.B. „work".<br />

7. Klicken Sie mit rechter Maustaste auf diesen Ordner <strong>und</strong> dann auf „SVN Checkout...". Sie<br />

müssen unter „URL of repository" ihr Repository angeben - i.d.R. wird das eben erstellte angezeigt.<br />

Klicken Sie auf HEAD Revision um den aktuellsten Status zu ziehen. Klicken Sie auf OK <strong>und</strong> sie<br />

sehen, welche Daten das SVN aus dem Repository holt.<br />

8. Der „work" Ordner hat jetzt ein kleines grünes Häkchen, genauso wie jede Datei. Ein grünes<br />

Häkchen bedeutet immer, dass diese Datei seit dem letzten Abgleich mit dem Repository nicht<br />

verändert wurde.<br />

Glückwunsch! Sie haben gelernt, wie Sie ein Repository erstellen, eine erste Dateiversion unter<br />

Revisionskontrolle stellen <strong>und</strong> in ein Repository importieren. Außerdem haben Sie gelernt, wie Sie<br />

eine Working Copy beziehen.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │54


Dateien verändern <strong>und</strong> committen<br />

Wollen wir unseren Sourcecode ein wenig verändern. Sie stellen fest, dass der Kameracode lieber<br />

in eine eigene Kamerafunction gehört, die von der main function aufgerufen werden soll. Sie<br />

schreiben nun stattdessen:<br />

function cam();<br />

function main ()<br />

{<br />

}<br />

level_load("room.wmb");<br />

wait(3);<br />

while (1)<br />

{<br />

}<br />

cam();<br />

wait(1);<br />

function cam ()<br />

{<br />

camera.pan += 5 * time_step;<br />

}<br />

Nachdem Sie auf „Speichern" geklickt haben, hat sich das Icon der Datei verändert:<br />

Das rote Ausrufezeichen signalisiert, dass die Datei verändert ist. Nun wollen Sie die Datei<br />

commiten, damit die Datei gesichert ist. Dazu klicken Sie mit der rechten Maustaste auf den „work"<br />

Ordner <strong>und</strong> dann auf „SVN commit ...". Im folgenden Fenster sehen Sie ein Feld für die Changelog,<br />

wo sie etwas eingeben können <strong>und</strong> ein Fenster, indem alle Änderungen angezeigt werden. Klicken<br />

Sie auf OK. Nun ist die Änderung im SVN verzeichnet. Ändern Sie nun wieder was im Code:<br />

schreiben Sie irgendwas rein, einen Kommentar zum Beispiel, <strong>und</strong> bauen Sie einen Fehler ein:<br />

//meine kleine Kamerafunktion<br />

function cam ()<br />

{<br />

camera.pan += 0 * time_step;<br />

}<br />

Die Datei ist wieder mit einem roten Ausrufezeichen versehen. Nun, das Programm läuft nicht.<br />

Nehmen wir mal an, sie wissen nicht mehr was Sie verändert haben <strong>und</strong> wollen das jetzt wissen -<br />

<strong>und</strong> nehmen wir mal an, sie wissen auch nicht mehr, welche Dateien Sie verändert haben. Klicken<br />

Sie einmal mit der rechten Maustaste auf den „work"-Ordner <strong>und</strong> dann auf „TortoiseSVN\\Check for<br />

modifications". Sie sehen dann einmal alle Änderungen auf einen Blick. Aha, Sie haben die Datei<br />

„main.wdl" geändert. Klicken Sie mit der rechten Maustaste auf die Datei <strong>und</strong> dann auf „Compare<br />

with base" - nun wird die Datei mit der letzten Version aus dem Repository verglichen. Dann sehen<br />

Sie folgendes:<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │55


Sie sehen links die letzte Fassung aus dem letzten Update / WC <strong>und</strong> rechts die Änderungen. Zeilen<br />

mit einem + Zeichen weisen auf eine Änderung oder einer neuen Zeile hin <strong>und</strong> - (Minus-) Zeichen<br />

auf veränderte, bzw. gelöschte Zeilen. Sie sehen, das der Kommentar neu ist <strong>und</strong> das sie die<br />

camera.pan - Zeile geändert haben. Sie sehen, dass da eine 0 steht. Die Kamera dreht also nicht -<br />

das ist der Fehler! - Ändern Sie ihn aber committen Sie ihn (vorerst) nicht.<br />

Neue Dateien, updates <strong>und</strong> merging<br />

Bevor jetzt weitere Features besprechen, ziehen Sie eine weitere Working Copy in den Ordner<br />

„work2". Dort müsste nun der fehlerhafte Code drin sein. In „work" haben Sie den ja schon<br />

korrigiert, aber noch nicht commited. „Work" hat also ein rotes Ausrufzeichen, während „work2" ein<br />

grünes Häkchen hat.<br />

Fügen Sie nun ein Sprite in „work" ein <strong>und</strong> stellen Sie diesen in ihr Level <strong>und</strong> kompilieren Sie die<br />

Levelfile erneut. Nun müssten ein paar level-Dateien ein rotes Ausrufezeichen haben. Der Sprite<br />

hingegen hat kein Symbol - die Datei steht nicht unter Versionskontrolle. Um diesen Sprite zu<br />

erfassen, klicken Sie mit einem Rechtsklick drauf <strong>und</strong> dann auf „TortoiseSVN\\add..". Die Datei hat<br />

ein blaues + Zeichen <strong>und</strong> wird beim nächsten Commit dem Repository hinzugefügt. Committen Sie<br />

diesen Stand des „work" Ordners.<br />

Stellen Sie sich vor, die WC im Ornder „work2" wäre auf dem PC eines anderen Programmierers.<br />

Der hat den Kamerafehler entdeckt <strong>und</strong> baut noch eine laufende Tilt-Veränderung ein:<br />

function cam ()<br />

{<br />

camera.pan += 2 * time_step;<br />

camera.tilt += 1 * time_step;<br />

}<br />

Er hat weder den Kommentar eingebaut, noch diesen Sprite. Er denkt sich, bevor er committed:<br />

„vielleicht hat ja schon jemand weiter gearbeitet".. er macht also ein update, indem er mit rechter<br />

Maustaste auf seine WC klickt <strong>und</strong> dann auf Update klickt. Er sieht, wie die Sprite-Datei geaddet<br />

wird, die Levelfiles geupdated wird bei der Script-Datei - die er gerade bearbeitet hat, steht<br />

„merged" - was heißt das? Er guckt in die Datei <strong>und</strong> stellt fest, dass dort z.B. der Kommentar neu<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │56


ist. Das SVN ist in der Lage, neue Änderungen von außen (durch ein Update) zu erkennen <strong>und</strong> die<br />

geänderten Dateien anzupassen, sodass beide Versionen zusammengefügt werden. Der<br />

Programmierer von „work2" startet sein Programm <strong>und</strong> sieht seine neue Kamerarotation <strong>und</strong> den<br />

geupdateten Sprite. Er ist zufrieden <strong>und</strong> committet die neue Version.<br />

Dateien verändern<br />

Gr<strong>und</strong>sätzlich gilt: alle Sachen, die man an einer Datei ändert, muss das SVN mitkriegen. Wenn Sie<br />

innerhalb vorhandener Dateien was ändern - die unter RC stehen - dann ist das ok. Wenn Sie aber<br />

- mit der Hand, also im Windows Explorer - Dateien löschen, umbenennen, verschieben o.ä., dann<br />

meckert das SVN.<br />

Dateien umbenennen<br />

Wir haben jetzt eine Date „sprite.bmp" in unseren Ordner getan, der im Level angezeigt wird. Wir<br />

wollen aber, das er anders heißt. Sie müssen jetzt über das SVN diese Datei umbenennen, sonst<br />

zeigt das SVN an, dass die Datei „sprite.bmp" fehlt <strong>und</strong> die umbenannte Datei wird als nicht RC<br />

stehend anerkannt - obwohl es ja prinzipiell die gleiche Datei ist. Klicken Sie mit der rechten<br />

Maustaste auf die Datei <strong>und</strong> dann auf „TortoiseSVN\\Rename..". Geben Sie im Dialogfeld<br />

„testSprite.bmp" ein. Durch ein blaues + Zeichen wird die Änderung signalisiert. Vergessen Sie<br />

nicht in der WMP Datei den Sprite abzugleichen <strong>und</strong> neu zu kompilieren.<br />

Dateien löschen<br />

Sie stellen fest, dass es in dem Ordner Dateien gibt, die Sie für das editieren des Levels nicht<br />

benötigen, weil sie sowieso immer automatisch erzeugt werden, wenn sie nicht vorhanden wären.<br />

Dazu gehören „*.bak" Dateien, als auch die Dateien „*.$$M", „*.$$w", „*.raw" <strong>und</strong> „*.wed".<br />

Markieren Sie alle diese Dateien <strong>und</strong> klicken Sie mit rechter Maustaste auf diese <strong>und</strong> dann auf<br />

„TortoiseSVN\\Delete". Die Dateien werden sowohl physikalisch aus dem work Verzeichnis entfernt<br />

als auch aus der Revisionskontrolle herausgenommen. Wenn Sie jetzt committen, wird das an das<br />

SVN Repository weitergegeben. Wenn ein anderer user jetzt ein update machen würde, würde das<br />

SVN bei ihm diese Dateien auch löschen.<br />

Dateien ignorieren<br />

Wenn Sie jetzt wieder an der WMP arbeiten, werden diese Dateien wieder erzeugt. Nun, es kommt<br />

darauf an, was unter RC steht - Ihnen ist es aber egal, ob diese Dateien bei Ihnen in der WC<br />

herumliegen. Sie können im SVN auch ignore-tags setzen, sodass das SVN diese Dateien „nicht<br />

sieht".. also ignoriert. Editieren Sie also die WMP (machen Sie den hollow cube größer oder so),<br />

speichern Sie die wmp ab <strong>und</strong> kompilieren Sie. Sie sehen dann, dass die neuen Dateien kein SVN<br />

Symbol haben:<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │57


Logs<br />

Bei jedem Commit können Sie eine Log-Message eingeben, die gespeichert wird. Das ist dann<br />

besonders interessant, wenn Sie wissen wollen, was bei jeder Revision geändert wurde. Das<br />

können Sie auf das gesamte unter RC stehende Projekt tun, aber auch nur für Ordner <strong>und</strong> auch für<br />

einzelne oder mehrere Dateien. Klicken Sie z.B. mit der rechten Maustaste auf den Sprite <strong>und</strong> dann<br />

auf „TortoiseSVN\\Show log". Sie sehen dann z.B. Folgendes:<br />

Sie können einen Zeitraum der Log (für diese Datei in diesem Fall) angeben, von dem Sie<br />

auswählen wollen. Dann steht in einem Fenster jede Revision, in der die Datei geändert wurde, wer<br />

die Datei geändert hat, welche Actions auf die Datei ausgeübt wurde(n), wann dies getan wurde<br />

<strong>und</strong> eine Kurzform der log message. Wenn Sie einen Eintrag auswählen, wird die Log dann<br />

angezeigt.<br />

Repository Browser<br />

Man kann sich auch die aktuelle „Head" (= Kopf) Revisionstruktur im Repository anschauen, oder<br />

eben eine spezielle. Dort wird dann die Verzeichnisstruktur des Repositories angezeigt <strong>und</strong> alle<br />

dazugehörigen Daten wann was von wem wie verändert wurde. Hier nun ein Beispiel eines<br />

größeren Repositories von mir:<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │58


Wann soll man immer commiten?<br />

Im Prinzip könnte man sagen, das dies egal ist. Wenn man viele Änderungen oder ein großes<br />

neues Feature oder sowas einbaut, so sollte man immer in kleinen Häppchen commiten - damit bei<br />

evtl. Fehlern schnell wieder reverted werden kann. Wenn man eher immer große commits macht,<br />

dann kann man beim späteren Rekonstruieren eventuell die Übersicht verlieren, weil zuviel auf<br />

einmal gemacht worden ist.<br />

Reverten<br />

Das reverten ist eigentlich ganz einfach. Wir wollen nun einen einfaches Beispiel machen: nehmen<br />

Sie den Testsprite, laden Sie ihn in ein Grafikprogramm <strong>und</strong> malen Sie was darauf, sodass er<br />

verändert wird. Committen Sie die neue Version. Malen Sie nochmal was drüber, <strong>und</strong> committen<br />

Sie nochmals. Die neue Revision hat nun eine Nummer, z.B. 10. Der Sprite in Revision 8 war also<br />

der ursprüngliche Stand. Nehmen Sie einmal an, dass ist eine Textur oder so <strong>und</strong> Sie als Grafiker<br />

haben neue Versionen hochgeladen.<br />

Änderungen tätigen, nicht commiten, aber reverten<br />

Nehmen Sie an, sie zeihen nun ein update <strong>und</strong> wollen den Sprite verändern (tun Sie dies!). Sie<br />

stellen fest, dass die Änderung schlecht aussieht <strong>und</strong> wollen zum Stand der WC. Klicken Sie mit der<br />

rechten Maustaste darauf <strong>und</strong> dann auf „TortoiseSVN\\Revert...". Sie sehen dann alle geänderten<br />

Dateien (in diesem Fall der Sprite). Klicken Sie auf OK <strong>und</strong> die Datei ist auf dem alten Stand - sie<br />

ist reverted worden.<br />

Auf eine ältere Revision reverten <strong>und</strong> als neue Revision commiten<br />

Wenn Sie nun feststellen, dass die allererste Version, z.B. aus Revision 8, viel besser aussieht als<br />

alle nachfolgenden Revisionen (oder das ein code damals funktionierte <strong>und</strong> alle Neuerungen<br />

danach nur schlechte bugfixes waren) <strong>und</strong> sie wollen diese jetzt wieder - so geht das auch! Stellen<br />

Sie sicher, dass die Datei auf dem Stand der WC ist (bei einer Änderung also erst reverten). Gehen<br />

Sie dann im SVN Menü auf „Update to Revision" <strong>und</strong> geben Sie die gewünschte Revision an.<br />

Wichtig: die Datei ist dann nicht auf dem Stand der aktuellen Revision! Sie müssen dann den<br />

Dateiinhalt kopieren, die Datei wieder auf die Head-Revision bringen (auch mit „Update to<br />

revision") <strong>und</strong> die aktuelle Dateiversion mit dem Duplikat der „zurückgeholten" Datei<br />

überschreiben. Wenn Sie jetzt commiten, ist dann der Inhalt der „alten" Revision wieder „neu".<br />

Alte Dateien, die früher mal gelöscht wurden, wiederherstellen<br />

Sie können wie oben gezeigt, im Repository-Browser alte Revisionen anschauen. Wenn Sie nun<br />

eine alte Datei, die früher einmal gelöscht wurde, wiederherstellen wollen, dann suchen Sie sich<br />

zunächst die letzte bekannte Revision der Datei heraus. Dann können Sie im Repo-Browser - wenn<br />

sie diese Datei gef<strong>und</strong>en haben - die Datei irgendwo auf ihrem Computer speichern. Dann haben<br />

Sie die Datei wiederhergestellt!<br />

Ein Blick über den Tellerrand<br />

Dies sind nur die Basisoperationen, die Sie kennen müssen. Es gibt viele Ausnahmesituationen,<br />

denen Sie begegnen (z.B. conflicts, filelocks, etc.) werden, aber weitere Details dazu finden Sie im<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │59


oben genannten OpenBook. Wie Sie das SVN als server einrichten, steht dort auch - eine Erklärung<br />

wie man das macht <strong>und</strong> das SVN für diesen Betrieb einstellt, würde den Rahmen dieses Artikel bei<br />

weitem sprengen. Dazu gehört nämlich unter anderem der uneingeschränkte Zugang zu einem<br />

Server. Ich bezweifle das der durchschnittliche Leser einen solchen Besitzt oder Geld für einen<br />

Root-Server ausgibt. Wer aber die notwendigen Ressourcen hat, sollte sie aber auch anwenden:<br />

erst durch serverbasierte RC kann man ein echtes Projekt durchziehen, bei denen die Mitglieder<br />

einer Gruppe weit verstreut sind. Gerade bei internationalen Projekten mit Zeitzonen usw. ist das<br />

überaus hilfreich.<br />

Eine weitere Software, die ich in diesem Zusammenhang erwähnen will, ist das sogenannte TRAC,<br />

welches man mit dem SVN nahtlos kombinieren kann. Es ist eine Art Projektmanagement<br />

Software, die Aufgaben über Tickets verteilt, die bestimmten Personen zuteilen kann. Man kann<br />

auch bugreports einreichen, in den Tickets Diskussionen führen (z.B. wenn es um neue Features<br />

oder reporduzierbare bugs geht). Über sogenannten GANTT charts kann man Zeitpläne zur<br />

Projektrealisierung durchführen <strong>und</strong> anzeigen - <strong>und</strong> vieles mehr!<br />

Ich bedanke mich für Ihre Aufmerksamkeit,<br />

mit spielerischen Grüßen,<br />

Christian Behrenberg<br />

Literaturangaben<br />

Version Control with Subversion; open book. URL:<br />

http://svnbook.red-bean.com/<br />

Subversion Website; URL:<br />

http://subversion.tigris.org/<br />

TortoiseSVN Website; URL:<br />

http://tortoisesvn.tigris.org/<br />

Wikipedia Artikel<br />

http://en.wikipedia.org/wiki/Revision_control<br />

http://de.wikipedia.org/wiki/Versionsverwaltung<br />

http://de.wikipedia.org/wiki/Subversion (Software)<br />

http://en.wikipedia.org/wiki/Comparison_of_revision_control_software<br />

Autorenwebsite:<br />

http://www.christian-behrenberg.de<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │60


Wings3d Tutorial Teil1<br />

Start!<br />

Hallo mein Name ist Ronny Leonhard <strong>und</strong> vielleicht kennt mich der ein oder andere aus dem <strong>3D</strong>GS<br />

Forum. Ich möchte heute in meinem ersten Tutorial erklären wie man Wings3d so einrichtet das<br />

man damit vernünftig arbeiten kann. Wie gesagt das ist mein erstes <strong>und</strong> ich werde in weiteren<br />

erklären wie man damit modelliert <strong>und</strong> Texturen auf dem Modell auflegt, bis hin zum exportieren<br />

<strong>und</strong> importieren im WED.<br />

Kurz was zur Software selbst, Wings3d ist ein kostenfreies <strong>3D</strong> Programm mit dem man 3d Modelle<br />

erstellen kann <strong>und</strong> auch für alles verwenden kann (darf). Downloaden könnt Ihr die Software bei<br />

www.wings3d.com.<br />

Startet euer Wings3d, für denjenigen der mit 3ds Max <strong>und</strong> G-Max gearbeitet haben sollte, ist die<br />

Bedienoberfläche was neues, denn in Wings3d gibt's keine gleichzeitigen Ansichten von „Top, Front,<br />

Left, Perspektive" hier wird immer in einer Ansicht gearbeitet. Man kann die Ansichten aber<br />

umstellen, aber später mehr dazu.<br />

Jetzt seht Ihr ein Rastermuster <strong>und</strong> die Richtungsanzeigen „X, Y, Z", Ihr könnt das Rastermuster<br />

<strong>und</strong> die Achsen rechts oben aus <strong>und</strong> einblenden. Was beim Arbeiten manchmal sehr hilfreich sein<br />

kann.<br />

Damit man besser versteht was ich erklären möchte, erstelle ich einen „Cube" ( rechte maustaste<br />

-> Cube ). Der Cube ist erstellt <strong>und</strong> nun möchten wir auch gern die hinteren Seiten bearbeiten<br />

oder zumindest sehen können, also müssen wir den Cube drehen. Das funktioniert in Wing3d mit<br />

dem Scrollrad, einfach klicken <strong>und</strong> schon kann man den Cube drehen. Soweit so gut, nun ist aber<br />

unser Modell etwas länger <strong>und</strong> ragt über die Bildschirmlänge hinaus, also muss man das Modell<br />

etwas verschieben um den Rest sehen zu können. Das geht so ohne weiteres nicht, dazu muss<br />

man die Standardeinstellungen verändern damit dies auch geht.<br />

Preferences -> Camera <strong>und</strong> stell bei Camera Mode auf „ 3ds Max". -> „OK".<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │61


Jetzt können wir das Modell verschieben <strong>und</strong> das geht mit dem Scrollrad. Das Wenden <strong>und</strong> Drehen<br />

funktioniert fast immer noch genauso nur das Ihr zum Drehen jetzt die Taste „Alt" dazu mit<br />

benutzen müsst, also „Alt + Scrollrad" <strong>und</strong> schon könnt Ihr das Modell wieder drehen.<br />

Wer es mag kann auch die Hintergr<strong>und</strong>farbe ändern, ich habe es bei mir gemacht weil ich es<br />

besser finde so zuarbeiten. Leider gibt's die Software nicht in deutsch aber wer polnisch oder<br />

schwedisch kann kann die Sprache umstellen. Es gibt auch noch andere Sprachen...<br />

So jetzt habt Ihr die optimalen Einstellungen um gute Ergebnisse zu produzieren. Im nächsten<br />

Tutorial erkläre ich wie man ein einfaches Modell erstellt.<br />

Viel Spaß beim modellieren! Ronny<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │62


Interview mit Ulf Ackermann, Gewinner des Conitec<br />

Spring Contests 2007<br />

3dgs Magazin<br />

Dein Spiel hat den letzten Conitec Contest gewonnen. Es sprüht vor lustigen Ideen <strong>und</strong> Features.<br />

Was hat Dich zum Prinzip Utz Wollewutz inspiriert?<br />

Ulf Ackermann<br />

Ich habe einige Marble Madness Clones gespielt zu der Zeit. Da gab es zum Beispiel eins mit einem<br />

Hamster in einer Kugel. Allerdings fand ich das recht trist, da die Umgebung nur aus farbigen<br />

Quadraten bestand. Ich bin ein grosser Fan von Sonic. Da dachte ich mir, ich probiere einfach mal,<br />

das Marble Madness Spielprinzip mit Jump and Run Einlagen zu würzen!<br />

3dgs Magazin<br />

Woher nimmst Du all die lustigen Ideen?<br />

Ulf Ackermann<br />

Nunja, die kommen mit der Zeit... Ausserdem ist einiges natürlich bewährt aus anderen<br />

Spielprinzipien, zum Beispiel die Powerups. Ich mag Schafe, das sind einfach lustige Tiere. Ich<br />

kann auch den Ton eines Schafes fast naturgetreu nachahmen, willst Du mal hören? ;-)<br />

3dgs Magazin<br />

Vielen Dank für das Angebot. ;-)<br />

Du hast die Newton Physik Engine sehr kreativ eingesetzt. Kannst Du uns einige Tipps in Bezug auf<br />

die Verwendung von Newton mitteilen?<br />

Ulf Ackermann<br />

Anfangs, als ich noch eine überschauliche Anzahl an Physikobjekten hatte, machte Newton<br />

keinerlei Probleme. Hat man hingegen zuviele Objekte, kann es unter ungünstigen Bedingungen<br />

abstürzen. Man sollte auch keine zu komplexen Modelle als Newtonentities nutzen! Am besten<br />

verstreut man die Objekte, so dass maximal 4-5 auf einmal miteinander kollidieren können. Das ist<br />

gut für die Performance! Für Kollision mit anderen Objekten, welche keine Newtonentities sind, hat<br />

es sich bewährt ein "normales" <strong>Gamestudio</strong>entity auf der selben Postion mitzuführen <strong>und</strong> die<br />

Kollisionen bequem mit Events zu organisieren.<br />

3dgs Magazin<br />

Das Spiel wirkt sehr sauber konstruiert <strong>und</strong> alles passt zusammen. Hattest Du einen Plan oder hast<br />

Du einfach losgelegt?<br />

Ulf Ackermann<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │63


Um ehrlich zu sein habe ich einfach angefangen. Ich hab mit Newton ein wenig herumgespielt <strong>und</strong><br />

das machte mir einen Mordsspass. Ich wollte diese Sandkastenidee aufgreifen. Das man quasi viel<br />

umwerfen kann, Kettenreaktionen in Gang setzt <strong>und</strong> so weiter. Anfangs war Utz noch ein Igel. Mit<br />

der Zeit ist das Ganze gewachsen <strong>und</strong> das Resultat ist ein Schaf gefangen in einer Kugel was sich<br />

durch 30+ Level rollen muss. Gibt es eigentlich schon den Begriff Jump & Roll?<br />

3dgs Magazin<br />

War dies Dein erstes Projekt?<br />

Ulf Ackermann<br />

Nicht wirklich. Ich habe schon eine Menge gemacht. Über manches bin ich im nachhinein nicht so<br />

stolz. Zum Beispiel gab es mal "Killerhuhn <strong>3D</strong>", das erste Moorhuhn in <strong>3D</strong>. Wenn ich mir das heute<br />

anschaue, ist es mir ein wenig peinlich. Zu meiner Verteidigung: Ich war damals erst 17 <strong>und</strong> es<br />

war mein erstes Projekt. Ansonsten hatte ich neben allerlei Experimenten einen<br />

Westernshooter/adventure angefangen. Screenshots davon gibt es noch in AUM 7.<br />

(http://www.coniserver.net/coni_users/web_users/pirvu/aum/aum7/english/images/danrecent_scr<br />

eenshots.jpg)<br />

3dgs Magazin<br />

Hast Du schon Pläne für die Zukunft?<br />

Ulf Ackermann<br />

Allerdings. Ich werde auf jeden Fall bei <strong>Gamestudio</strong> bleiben. Weil ich glaube, daß ich als quasi<br />

Einzelkämpfer mit der Hilfe von ein paar guten Modellern nur als Casual-Game Entwickler eine<br />

Chance habe. Grosse Projekte werden es nicht - ich habe allerdings einige spassige Ideen für<br />

kleinere Spiele. Mehr möchte ich noch nicht verraten.<br />

3dgs Magazin<br />

Was gefällt Dir an <strong>Gamestudio</strong> besonders gut?<br />

Ulf Ackermann<br />

Es ist "einfach", <strong>und</strong> läuft auf sehr unterschiedlicher Hardware nahezu absturzfrei. Das ist wohl das<br />

grösste Plus <strong>und</strong> sehr wichtig wenn man Spiele für eine breite Zielgruppe mit "älteren" Rechnern<br />

entwickeln möchte. Die Community ist wohl auch eine der besten, die mir über den Weg gelaufen<br />

ist bisher.<br />

3dgs Magazin<br />

Und was findest Du eher nicht so toll?<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │64


Ulf Ackermann<br />

Der Multiplayerteil ist momentan noch sehr unkomfortabel. Es ist zwar gr<strong>und</strong>sätzlich möglich ein<br />

Mehrspielerspiel zu entwickeln, allerdings ist der Aufwand extrem hoch. Der 2D Part gefällt mir<br />

auch noch nicht so (mein Menü hat ca. 5000+ Zeilen Code), ein Drag & Drop Gui Editor würde der<br />

Engine gut tun. Ausserdem sollte der Renderer etwas schneller werden. Die Map/Modelleditoren<br />

sind zwar okay, aber auch hier gibt es innovativere, nutzerfre<strong>und</strong>lichere Entwicklungen.<br />

3dgs Magazin<br />

Was würdest Du Anfängern raten?<br />

Ulf Ackermann<br />

Lest meinen Blog (http://www.ackbytes.de)! ;-)<br />

Nein, quatsch. Ich rate ganz klassisch dazu, als erstes die Gr<strong>und</strong>lagentutorials durchzuarbeiten.<br />

Danach sollte man sich ein total einfaches Spielprinzip hernehmen (z.b. Pacman, Asteroids,<br />

Snake...) <strong>und</strong> das probieren mit <strong>Gamestudio</strong> nachzubauen. Natürlich mit eigenen<br />

Änderungen/Ergänzungen. Man sollte es zuendebringen! Also selbst wenn es nur ein Level hat, ein<br />

komplettes Spiel daraus machen mit Installationsprogramm, Hilfedatei usw. Daraus lernt man<br />

enorm. Spieleentwicklung ist nicht nur Spass <strong>und</strong> dabei lernt man auch unangenehme Aufgaben zu<br />

erledigen.<br />

Vielen Dank an Ulf, daß er sich die Zeit genommen hat unsere Fragen zu beantworten!<br />

Das Interview wurde von Torsten Fock im Auftrag des 3dgs Magazins durchführt.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │65


Interview mit Sven Paroth, dem Zweitplatzierten im<br />

Conitec Spring Contest 2007<br />

3dgs Magazin<br />

Du hast mit "Angelas World" ein sehr reizvolles Spiel entwickelt, dass unter anderem von seiner<br />

Einfachheit <strong>und</strong> Deinem besonderen Style lebt. Welches Programm hast Du benutzt um die<br />

stilvollen Grafiken zu erstellen?<br />

Sven Paroth<br />

Alle Grafiken wurden mit Adobe Photoshop CS erstellt, welches ich leider nur auf meiner Arbeit<br />

nutzen kann. An ungeduldigen Tagen hab ich dann Zuhause mit dem kostenlosen Programm<br />

"GIMP" gearbeitet.<br />

3dgs Magazin<br />

Arbeitest Du mit einem Grafiktablett?<br />

Sven Paroth<br />

Nein. Da meine Grafiken alle nur einfarbig sind <strong>und</strong> ich jede Art von r<strong>und</strong>en Formen vermeiden<br />

wollte, reicht da eine Maus aus. Ich finde es auch persönlich angenehmer mit dem "Pen-Tool" von<br />

Photoshop (erstellen von Pfaden) mit der Maus zu arbeiten, als mit einem Grafiktablett, da das<br />

Nachbearbeiten der Pfade präziser mit einer Maus ist (meiner Meinung nach).<br />

3dgs Magazin<br />

Wie inspirierst Du Dich?<br />

Sven Paroth<br />

Wenn ich das wüsste... Ich kann das nicht erzwingen <strong>und</strong> mir sagen "so, jetzt denk dir mal was<br />

neues aus". Das muss einfach von selbst kommen. Inspirieren tun mich sicherlich so einige Sachen<br />

wie Menschen, Kunststile, Musik, etc...<br />

3dgs Magazin<br />

Der Lohn dafür war der zweite Platz im letzten GS-Contest. Hast Du damit gerechnet?<br />

Sven Paroth<br />

Mit dem zweiten Platz hab ich auf keinen Fall gerechnet. Ich war mir zwar mittlerweile bewusst,<br />

dass das Spiel bei einigen Leuten gut ankam, aber als ich die Liste der teilnehmenden Projekte<br />

gesehen habe, hab ich nicht geglaubt unter die besten 5 zu kommen. Projekte wie Utz Wollewutz,<br />

Memowar oder ähnliches sind einfach umfangreicher als mein Projekt. Mir war´s besonders wichtig<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │66


zu sehen was man von meinem Projekt hält, egal ob positiv oder schlecht. Von daher bin ich sehr<br />

dankbar für den 2. Platz.<br />

3dgs Magazin<br />

Du hast im Forum schon des öfteren davon geschrieben, dass Du manchmal ein kleines<br />

Motivationstief hast. Das geht uns allen so. Wie gehst Du damit um <strong>und</strong> wodurch steigerst Du<br />

Deine Motivation?<br />

Sven Paroth<br />

Ohja das Motivationstief... Ich denke das ist das Hauptproblem Nr. 1 bei mir <strong>und</strong> vielen anderen,<br />

was das scheitern an Projekten betrifft. Da sich meine Stimmung sehr häufig ändert <strong>und</strong> leicht von<br />

vielen Dingen beeinflusst wird, gabs bei mir wirklich Wochen bis gar Monaten wo ich absolut keine<br />

Motivation für irgendwelche Projekte hatte. Um das bei "Angelas World" zu ändern, hab ich<br />

eigentlich recht wenig getan. Neue Motivation hab ich aber aus den ganz vielen positiven<br />

Kommentaren zu meinem Projekt gewonnen. Sowas baut schon sehr auf. Im neuen Projekt,<br />

"Angelas World 2", hab ich allein die Motivation vom Vorgängertitel mit eingebracht. Zur Zeit läuft<br />

alles super <strong>und</strong> meine Motivation bleibt dauerhaft oben, was vor allem daran liegt, dass ich viel<br />

mehr plane als vorher, mir Milestones setze, <strong>und</strong> die richtige Musik beim arbeiten auswähle.<br />

3dgs Magazin<br />

Standen alle Features des Spiels von vornherein fest oder hast Du "ins Blaue hinein" entwickelt?<br />

Sven Paroth<br />

Um ehrlich zu sein, nein. Das ganze Projekt basierte nur auf den Gr<strong>und</strong>gedanken "Ich will ein Spiel<br />

FERTIGSTELLEN". Die Gr<strong>und</strong>idee für das Spiel hat mir meine Fre<strong>und</strong>in verschafft. Bei der Grafik<br />

habe ich vorher immer auf die "Masse" geschaut, was denen eventuell gefallen kann. Dadurch hab<br />

ich oft Probleme beim Umsetzen bekommen. Aus dem Gr<strong>und</strong> wollte ich diesesmal einfach meinen<br />

persönlichen Stil nutzen <strong>und</strong> hatte bedenken das er bei niemanden gefallen finden würde. Mehr<br />

Planung gabs eigentlich nicht. Der Rest kam durch meine Laune <strong>und</strong> wurde einfach "ins Blaue<br />

hinein" entwickelt, um´s mal mit deinen Worten zu sagen.<br />

3dgs Magazin<br />

Was gefällt Dir an <strong>Gamestudio</strong> besonders gut?<br />

Sven Paroth<br />

Besonders gefällt mir einfach die Möglichkeit, mit einfachen Mitteln in kurzer Zeit wirklich<br />

"brauchbare" Ergebnisse zu erzielen. Am Anfang kann man sich als Beginner mit Templates,<br />

fertigen Modellen <strong>und</strong> Scripten bereits kleinere Spiele zusammenbauen. Wenn man dann<br />

konkretere Projekte angehen möchte (egal welches Genre), schreibt man sich eben alles selbst,<br />

gerade mit der A7 Engine <strong>und</strong> Lite-C. Zudem gibt es eine super Community, die bei Fragen oft gute<br />

Antworten liefern, <strong>und</strong> durch Plugins das <strong>3D</strong>GS immer weiter ausbauen.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │67


3dgs Magazin<br />

Und was findest Du eher nicht so toll?<br />

Sven Paroth<br />

Schlecht finde ich eigentlich nichts an <strong>3D</strong>GameStudio. Leute, die dauernd die A6 Engine mit der<br />

Unreal 3 Engine oder ähnlichem vergleichen, haben einfach den Sinn für die Realität verloren. Es<br />

hat schon seine Gründe wieso Engines wie die Unreal 3 Engine mehrere tausende Dollar kosten. Es<br />

war auch mit Sicherheit nie das Ziel von Conitec, eine ähnliche Engine zu entwickeln. Meiner<br />

Meinung nach gibt es keine bessere Engine für Neulinge <strong>und</strong> Fortgeschrittene in der Games<br />

Industry als die A6 Engine. Man bekommt extrem viel für sein Geld <strong>und</strong> muss nur lernen wie man<br />

selbst an seine Ziele kommt. Die Engine allein macht das Spiel nicht qualitativ. Wer dann<br />

irgendwann mal reich ist <strong>und</strong> eine große Firma gründet, kann dann gerne zu den Königen der<br />

Engines greifen<br />

3dgs Magazin<br />

Was würdest Du Anfängern raten?<br />

Sven Paroth<br />

Ich rate Leuten sich erstmal die Gr<strong>und</strong>lagen mit der A6 Engine beizubringen. Dabei hilft es, das<br />

Manual, Tutorials oder einfach Scripte von existierenden Projekten anzuschauen. Dann kann man<br />

irgendwann anfangen, mit den Templates oder eigenen Scripten, kleine Spiele zu programmieren.<br />

Geht auf Freewareseiten, schaut euch kleine Spiele an <strong>und</strong> versucht das ganze mit der A6 Engine<br />

umzusetzen. Besonders wichtig ist hier bei die Planung! Um so früher man damit anfängt, desto<br />

schneller wird man für spätere, größere Projekte Design Dokus <strong>und</strong> Konzepte schreiben können.<br />

Ich hab ebenfalls viel zu oft gesagt das ich sowas nicht brauche, wie z.B. bei Angelas World. Das<br />

war der Hauptgr<strong>und</strong> für meine Motivationstiefs. Im zweiten Teil ist alles schriftlich festgehalten <strong>und</strong><br />

man sieht direkt was realisierbar ist, was zu tun ist, wie Umfangreich das Projekt ist <strong>und</strong> kann so<br />

viel gezielter <strong>und</strong> Motivierter arbeiten! Und bitte, fangt garnicht erst mit MMORPG's oder des<br />

gleichen an. Sowas erfordert Jahre lange Erfahrung <strong>und</strong> ein professionelles Team.<br />

Im Namen des 3dgs Magazins bedanke ich mich ganz herzlich bei Sven "Kihaku" Paroth für die<br />

Beantwortung der Fragen.<br />

Das Interview wurde von Torsten Fock im Auftrag des 3dgs Magazins durchführt.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │68


Interview mit Johann Christian Lotter, dem "Vater"<br />

des <strong>3D</strong> <strong>Gamestudio</strong>s<br />

JCL gibt Antworten<br />

3dgs Magazin<br />

Mit Lite-C schließen Sie eine Produktlücke <strong>und</strong> machen zugleich <strong>Gamestudio</strong> wesentlich flexibler.<br />

Wie kamen Sie auf diesen kleinen Geniestreich? Was hat Sie inspiriert?<br />

JCL<br />

Lite-C ist kein Geniestreich, sondern nur die logische Fortentwicklung einer reinen Skriptsprache zu<br />

einer Programmiersprache. C-Skript erlaubte nur Zugriff auf die Engine-Funktionen, lite-C dagegen<br />

Zugriff auf alle Softwarebibliotheken des PC, insbesondere die DirectX-Funktionen. Dies ist ein<br />

konsequenter Schritt für <strong>Gamestudio</strong> von einem reinen Spieleentwicklungssystem hin zu einem<br />

universellen Entwicklungssystem für alle möglichen Programme.<br />

3dgs Magazin<br />

Vielen Usern mißfällt etwas die die Art, in der neue Features angekündigt werden. Einige hätten<br />

gerne einen "Fahrplan", nach dem sie die Entwicklung größerer Projekte hinreichend planen<br />

können. Auch wenn Sie verständlicherweise keine genauen Angaben machen können - wäre nicht<br />

eventuell eine grobe "Timetable" denkbar?<br />

JCL<br />

Diesen Wunsch kann ich verstehen. Wir haben im Büro ein grosses Whiteboard, auf dem Features<br />

mit Hilfe von Klebezetteln auf Termine verteilt sind. Diese Klebezettel lassen sich leicht abnehmen<br />

<strong>und</strong> neu gruppieren, <strong>und</strong> das passiert auch ab <strong>und</strong> zu. Eine feste Timetable hingegen hat die<br />

Eigenschaft, sich zu verselbständigen <strong>und</strong> das Kommando zu übernehmen. Entweder müsste ich<br />

mich strikt daran halten (schlecht für mich) oder sie immer wieder abändern (schlecht für User, die<br />

sich darauf verlassen). Deshalb lasse ich das lieber bleiben. Wir werden aber den Forecast<br />

umgestalten, so dass User besser erkennen können, in welchem Entwicklungsstand sich die<br />

verschiedenen Features befinden.<br />

3dgs Magazin<br />

Was hat Sie dazu bewogen Lite-C <strong>und</strong> MED als Freeware anzubieten? (anm.: nicht für kommerzielle<br />

Zwecke)<br />

3dgs Magazin<br />

Ich kann es mir natürlich nicht verkneifen <strong>und</strong> es muß ja auch sein... Können Sie uns irgend etwas<br />

über die Verbindung zu Atari mitteilen? Wir wollen uns doch nur für Sie freuen.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │69


JCL<br />

Es freut mich, wenn ich mit einer Antwort gleich zwei Fragen erledigen kann: Atari haben Sie es zu<br />

verdanken, dass lite-C <strong>und</strong> MED Freeware sind. Leider kann ich erst in ein paar Wochen mehr dazu<br />

sagen.<br />

3dgs Magazin<br />

Sie haben eine besondere Art von Humor, die oftmals auf Logik begründet ist. Eigentlich schon ein<br />

Markenzeichen. Waren Sie - mit Verlaub - schon immer so?<br />

JCL<br />

Wer mich kennt, weiss, dass ich nicht besonders witzig bin. Der Spassvogel in unserem Team ist<br />

Doug.<br />

3dgs Magazin<br />

Gibt es für Sie ein "Lieblingfeature" an der Acknex Engine?<br />

JCL<br />

Ja, ein eher unauffälliges Feature: das Template-System mit dem sich selbst editierenden<br />

Sourcecode per Kommentarmarken.<br />

3dgs Magazin<br />

Wo sehen Sie <strong>Gamestudio</strong> in fünf Jahren? Haben Sie eine Vision?<br />

JCL<br />

Mit dieser Frage werden oft Kandidaten in Bewerbungsgesprächen genervt: Wo sehen Sie sich in<br />

fünf Jahren? Für <strong>Gamestudio</strong> hängt es davon ab, wie sich die PC-Hardware weiterentwickelt. In fünf<br />

Jahren haben wir die A8 Engine, die keinen Map-Compiler mehr benötigt <strong>und</strong> nicht nur das<br />

Rendern, sondern vermutlich auch Physik, Kollisionserkennung <strong>und</strong> Pathfinding per Hardware<br />

erledigt. Und wir haben ein Template-System, das automatisch viele Gr<strong>und</strong>typen von Spielen <strong>und</strong><br />

Simulationen mit "Wizard"-Funktionen erzeugt.<br />

3dgs Magazin<br />

Warum Hilbert´s Hotel? Warum die Unendlichkeit? Können Sie uns etwas über Ihre zweite Passion<br />

erzählen?<br />

JCL<br />

Warum die Unendlichkeit? Ich kann mir schlecht vorstellen, dass es jemanden gibt, den die<br />

Unendlichkeit gar nicht interessiert. Wer aber mehr wissen will, kann sich den Einleitungs-Sermon<br />

auf www.unendliches.net durchlesen.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │70


3dgs Magazin<br />

Mal anders gefragt: Gibt es einen Rat, den Sie ambitionierten <strong>und</strong> erfahrenen Entwicklern mit auf<br />

den Weg geben möchten?<br />

JCL<br />

Ambitionierte <strong>und</strong> erfahrene Entwickler brauchen keinen Rat von mir. Für weniger erfahrene<br />

Entwickler hätte ich den Rat, ihre Ambitionen solange zu zügeln, bis ihre Erfahrungen aufgeholt<br />

haben.<br />

Mit fre<strong>und</strong>lichem Gruss jcl / Conitec<br />

Vielen Dank Herr Lotter, daß Sie sich die Zeit genommen haben auf unsere Fragen zu antworten.<br />

Das Interview wurde von Torsten Fock im Auftrag des 3dgs-Magazins durchgeführt.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │71


SEED_IT for <strong>3D</strong>GS<br />

SEED_IT ist das hilfreiche Werkzeug für <strong>3D</strong>GS, welches die Verteilung <strong>und</strong> Platzierung von Objekten<br />

(Modelle/Sprites/Entities) bei der Levelgestaltung einfach <strong>und</strong> komfortabel macht.<br />

Mit nur wenigen Mausklicks ist es möglich einen gesamten Level, eine Landschaft <strong>und</strong> vieles andere<br />

zu erstellen <strong>und</strong> zu verändern. Mit SEED_IT hat das langwierige Platzieren einzelner Objekte ein<br />

Ende.<br />

Aber SEED_IT kann noch mehr...<br />

Mit den zahlreichen Optionen kann die Sichtbarkeit, zusätzliche (benutzerdefinierte)<br />

Aktionen/Funktionen, die Positionierung, die Größe, das Aussehen, das Material, Bewegung <strong>und</strong><br />

Animation, ..., der einzelnen Objekttypen schnell eingestellt <strong>und</strong> jederzeit verändert werden.<br />

SEED_IT generiert aus den Einstellungen performantes c-script welcher für spezielle Wünsche<br />

auch einfach erweiterbar ist.<br />

Wie funktioniert SEED_IT?<br />

SEED_IT verwendet je Objektplatzierung eine sogenannte SEEDMAP. Diese SEEDMAP ist ein<br />

einfaches Abbild der Objektverteilung anhand der drei Gr<strong>und</strong>farben:<br />

Jede der drei Gr<strong>und</strong>farben (R/G/B) repräsentiert dabei einen Objekttyp welcher wiederum aus bis<br />

zu zehn verschiedenen Modelle, Sprites, Entities bestehen kann.<br />

Der Farbwert (0..255) der einzelnen Gr<strong>und</strong>farben kann dabei auch noch die Dichte der<br />

Objektverteilung bestimmen.<br />

Die Verteilung der Objekte, welche sehr schnell in Echtzeit im Spiel durchgeführt wird, ist somit<br />

eine Projektion der Objekte nach der SEEDMAP auf das Terrain oder Modell (SEEDGROUND).<br />

Ein SEEDGROUND muss nicht zwingend sichtbar sein (z.B. bei Asteroiden).<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │72


Das Erstellen eines Levels in drei Schritten<br />

Zum Erstellen eines Levels mit SEED_IT sind nur drei Schritte notwendig:<br />

1. Vorbereiten des Levels, auswählen der Modelle <strong>und</strong> erstellen der SEEDMAP.<br />

2. Definieren der Objekttypen <strong>und</strong> deren Eigenschaften mit SEED_IT sowie das generieren des<br />

Scriptes mit einem Mausklick.<br />

3. Einmalig das Einbinden des erzeugten Scriptes in das Projekt <strong>und</strong> auswählen der Seed-Action für<br />

das Terrain.<br />

Nachträgliche Änderungen am Leveldesign durch Neuplatzierung, Umsortierung, ändern der<br />

Modelle oder deren Eigenschaften ist dann nur noch eine Sache von Sek<strong>und</strong>en.<br />

Die Einstellungen in SEED_IT mit wenigen Mausklicks verändern, das Script neu generieren, <strong>und</strong><br />

im Nu ist das Aussehen des Levels verändert.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │73


SEED_IT bietet aber noch viel mehr!<br />

- Aus-/einblenden der Objekte mit weichen Übergängen mit frei definierbarem Abstand<br />

- automatisches entfernen/erzeugen der Objekte zur Reduzierung des Speicherverbrauchs<br />

- Objektanimation oder -bewegung (Wind, Rotation, ...)<br />

- Einstellen der physikalischen Eigenschaften der Objekte (<strong>3D</strong>GS pro erforderlich)<br />

- Wettersimulation mit nur einem Schalter - einfache LOD-System Konfiguration<br />

- einfaches Einstellen des fog-Systems<br />

- Objektskills <strong>und</strong> -flags vordefinieren, Skins (fix/random Skin), Material (Material-LOD (einstufig))<br />

- pixelgenaue Platzierung von einzelnen Modelle bis zur freien Verstreuung von vielen Modellen<br />

- <strong>und</strong>, <strong>und</strong>, <strong>und</strong>...<br />

Laden Sie sich die Demo herunter unter http://www.gameus.de <strong>und</strong> lassen Sie von nun an<br />

SEED_IT for <strong>3D</strong>GS die Arbeit der Objektplatzierung übernehmen.<br />

SEED_IT for <strong>3D</strong>GS Version 1.0 kostet nur € 25,- /~$33.-<br />

Also nichts im Vergleich zu der Zeit für mühevolle manuelle Levelgestaltung.<br />

Vielen Dank an Ulrich "mercuryus" Seiffert für die Erklärung des Tools <strong>und</strong> die Bereitstellung einer<br />

Version für´s Autorengewinnspiel.<br />

<strong>3D</strong> GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007 │74

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!