3D GAMESTUDIO-Magazin Ausgabe 05 | Juni 2007 1

Transcription

3D GAMESTUDIO-Magazin Ausgabe 05 | Juni 2007 1
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│1
3D Gamestudio und MySQL
von Wicht
Hallo und herzlich willkommen zu meinem ersten Tutorial. In diesem werdet Ihr lernen, wie man
mit einer 3dgs-Anwendung Daten an einen MySQL-Server senden kann. Und auch empfangen.
Und wozu? Nun, überall da, wo jeder, der Euer Spiel benutzt, auf zentral gelagerte Daten (auch von
anderen Benutzern) zugreifen kann. Eine Möglichkeit wäre z.B. ein Online-Highscore-System. Ein
Nutzer sendet seine erreichte Punktezahl an eine MySQL-Datenbank und sieht sofort, welche
Punkte die anderen Spieler erreicht haben. Oder wie wäre es mit einem rundenbasierten Spiel?
Oder einem Chat? Oder oder oder ... Möglichkeiten gibt's genug.
Was brauchen wir?
Zunächst einmal das 3D Gamestudio. Soweit ich weiß, können alle 3DGS-Editionen DLLs
ansprechen. Ist doch prima, oder? Und dann natürlich die gshttp.dll von Peacekeeper (zu finden
unter http://www.peacekeeper.com/3dgs). Und die ist auch noch kostenlos. Was will man mehr.
Ach ja, ein funktionierender MySQL-Server wäre auch nicht schlecht ;-)
Achtung: Ich hatte Probleme, die Anweisung HTTP_POST zu verwenden. Stattdessen verwendete
ich die HTTP_GET Anweisung. Außerdem müssen Sonderzeichen wie Leerzeichen, Ü,Ä,Ö usw. noch
umgewandelt werden. Aus diesem Grund habe ich die DLL um eine weitere Funktion ergänzt, die
genau das macht.
Die modifizierte DLL (gshttp.dll) kann unter http://www.darkware.de/3dgsmysql_tut/gshttp.dll
runtergeladen werden.
Wer sich zunächst einmal die ganze Materie anschauen will, ohne gleich ein Webhosting-Paket zu
ordern, kann sich auch die Kombination Apache->PHP->MySQL lokal installieren. Damit kann man
alles offline testen. Wie diese Programme/Module installiert werden, steht in zahlreichen
Anleitungen im Internet.
Wer jetzt genau aufgepasst hat, dürfte sich folgendes fragen: Nanu? Wozu auch noch den ApacheWebserver und PHP? Ich dachte immer, man kann einen MySQL-Server auch direkt ansprechen. Ihr
habt recht. Natürlich geht das. Nur die meisten Webhoster wollen das aus sicherheitsrelevanten
Gründen nicht und sperren den direkten externen Zugriff auf den MySQL-Server. Um aber dennoch
unser Ziel zu erreichen, müssen wir PHP verwenden.
Ein erster Test
Jetzt wollen wir aber endlich mal was auf dem Bildschirm sehen.
Erstellt eine neue 3dgs-Anwendung (nach Möglichkeit ohne die Templates zu benutzen) und kopiert
die gshttp.dll in Euer Projektverzeichnis.
Jetzt brauchen wir noch eine php-Datei. Die könnte etwa so aussehen:
Die Datei mit dem Namen "textausgabe.php" ( den Namen könnt Ihr natürlich selbst wählen ) liegt
jetzt auf meinem Webserver und kann bereits über einen Browser abgerufen werden.
Bei mir sieht die URL so aus: "http://www.darkware.de/3dgsmysql_tut/textausgabe.php". Und was
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│2
macht die php-Datei? Nun, sie gibt nur einen einfachen Text aus. Mehr nicht.
Im Hauptskript unserer 3dgs-Anwendung erstellen wir zunächst unser Grundgerüst.
Die Zeilen 13-24 sollten eigentlich klar sein. Interessant sind allerdings die Zeilen 4-9. Über die
"dllfunction"-Anweisung wird der A6-Engine mitgeteilt, welche weiteren Funktionen ihr durch eine
DLL zusätzlich zur Verfügung gestellt werden. In unserem Beispiel sind es ein Teil der Funktionen,
die in der Datei gshttp.dll stehen.
Und nun erweitern wir unsere main-Funktion um diese neuen Befehle.
Und das kommt dabei heraus:
Jetzt haben wir's schon geschafft. Unsere Anwendung greift auf eine php-Datei zu, die irgendwo im
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│3
Internet erreichbar ist und liefert deren Ergebnis zurück.
Die neuen Anweisungen im Überblick:
HTTP_CREATE erstellt einen neuen HTTP-Client mit einer ID-Nummer. Es können also entsprechend
mehrere Clients gleichzeitig erstellt werden. Sicherheitshalber sollte man sich aber mit nur einem
begnügen.
HTTP_GET ruft schließlich unter der gleichen ID wie HTTP_CREATE eine Datei auf dem Webserver
auf. In unserem Beispiel "http://www.darkware.de/3dgsmysql_tut/textausgabe.php".
HTTP_IsWorking ist ganz wichtig. Diese Funktion überprüft, ob der Webserver mittlerweile mit
seiner Arbeit fertig ist. Sollte dem nicht so sein, müssen wir eben noch etwas warten. Wer will
schon mit Daten arbeiten, die noch nicht da sind ;-)
HTTP_RESULTS beinhaltet schließlich das Ergebnis unserer Webserver-Anfrage. In diesem Beispiel
den String "Der Gargamel mag keinen einzigen Schlumpf !!!".
HTTP_FREE beendet wieder den HTTP-Client.
Wichtig ist, dass bei all diesen Anweisungen immer die gleiche ID-Nummer vergeben wird. In
diesem Fall ist das immer 0. Grundlegend war's das schon. Spielt etwas damit, um ein Gefühl für
die neuen Befehle zu bekommen.
Und der MySQL-Zugriff?
Nun, diejenigen die sich mit php auskennen, dürften an dieser Stelle schon jubeln. Allen anderen
sei gesagt, dass der reine MySQL-Zugriff über php realisiert wird.
Und das schauen wir uns jetzt mal an.
Wir legen uns erstmal eine Tabelle via phpMyAdmin an.
Ein Datenbank-Tutorial liegt mir zwar fern, dennoch möchte ich auf einige wenige, aber wichtige,
Dinge eingehen. Das erste Feld sollte immer eine laufende Nummer UND ein Primärschlüssel sein.
Dadurch hat man die Möglichkeit, auch inhaltlich gleiche Datensätze zu unterscheiden. In diesem
Screenshot könnt Ihr sehen, das das erste Feld vom Typ "int" (Ganzzahl) in der Spalte "Extra" ein
"auto-increment" besitzt. Das heißt nichts weiter, als das bei jedem neuen Datensatz die Nummer
des Feldes um den Wert 1 erhöht wird. Der untere Screenshot verdeutlicht das.
Das Feld "3dgsmysql_tut_nr" ist genau dieses Feld mit dem Primärschlüssel und dem Extra "autoincrement".
Hinweis: phpMyAdmin ist eine in der Skriptsprache PHP geschriebene Webseite, mit deren Hilfe
MySQL-Datenbanken recht komfortabel verwaltet werden können.
Kostenloser Download unter http://www.phpmyadmin.net.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│4
OK, wir haben also unsere Tabelle, mit mehr oder weniger sinnvollem Inhalt, angelegt. Als
nächstes erstellen wir eine neue php-Datei, welche den gesamten Inhalt der Tabelle ausliest.
Zunächst brauchen wir aber eine php-Datei, welche die Zugangsdaten enthält. Sie heißt
"global.php".
Und dann noch die php-Datei, die den Datenbankinhalt ausliest.
Das obige Bild zeigt den Inhalt der Datei "textausgabe_db.php".
Die Datei "textausgabe_db.php" bindet die Datei "global.php" mit Hilfe des include-Befehls ein.
Also ganz analog dem include-Befehl in C-Script. Man könnte also auch die Datei "global.php"
weglassen und die Zugangsdaten direkt in die Datei "textausgabe_db.php" eintragen. Mit ständig
ansteigender Anzahl an php-Dateien wird man jedoch die Auslagerung der Zugangsdaten in eine
separate Datei zu schätzen wissen.
In den Zeilen 7-10 wird eine Datenbankverbindung aufgebaut und eine SQL-Anweisung gesendet.
Die Zeile 12 hätten wir sogar weglassen können.
In der Zeile 13 wird ermittelt, wieviele Datensätze als Ergebnis der Abfrage zurückgeliefert wurden.
Dieser Wert wird benötigt, damit wir eine Schleife ausführen können (Zeile 15-21), um jeden
einzelnen Datensatz mithilfe der echo-Anweisung auszugeben (Zeile19). Die Zeile 20 ist nur dazu
da, einen Zeilenvorschub zu integrieren.
Die php-Anweisung mysql_result in den Zeilen 16 und 17 liest die einzelnen Werte des aktuellen
Datensatzes aus. Der erste Parameter ($res) beinhaltet das gesamte Abfrageergebnis. $i definiert
den aktuellen Datensatz in der for-Schleife. Der dritte und letzte Parameter definiert des Feld.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│5
Schaut Euch dazu nochmal den unteren Screenshot an. Wenn der dritte Parameter 0 ist, dann
meinen wir damit das erste Feld. Also "3dgsmysql_tut_nr". Bei einer 1 entsprechend das Feld
"dw_3dgsmysql_tut_text", usw. ...
In unserer C-Skipt-Datei ändert sich allerdings nicht viel. Wir haben ein weiteres Textelement,
welches den Inhalt unserer "textausgabe_db.php" darstellt.
HTTP_CREATE, HTTP_GET usw. sollten an dieser Stelle auch keine weiteren Fragen aufwerfen.
Und hier ist das Ergebnis ...
Mehr gibt's eigentlich zum empfangen von MySQL-Daten nicht zu sagen.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│6
Senden von Daten an einen MySQL-Server
Auch an dieser Stelle dürften Anwender, die mit php Erfahrung haben, jubeln. Um Daten an einen
MySQL-Server über eine php-Datei zu senden, werden diese einfach an das Ende der URL
angehängt. Das sieht dann z.B. so aus:
"http://www.darkware.de/3dgsmysql_tut/neuerdatensatz.php?user=Wicht&text=lustig".
Der php-Datei "neuerdatensatz.php" werden die Variable "user" mit dem Inhalt "Wicht" und die
Variable "text" mit dem Inhalt "lustig" übergeben. Und mit diesen Variablen ( und deren Werten )
kann man in PHP weiterarbeiten.
Wir werden unsere kleine 3dgs-Anwendung so erweitern, dass gleich 2 Werte an einen MySQLServer übertragen werden. Dazu habe ich zunächst die Tabelle um ein weiteres Feld erweitert.
Wie Ihr sehen könnt, wurde mit phpMyAdmin ein neues Feld "username" zwischen den beiden
schon vorhandenen Feldern eingefügt ( Typ: varchar; Länge 60 ).
Die Datei "neuerdatensatz.php, welche Daten an den MySQL-Server sendet, sieht so aus:
Zeile 3: Den include-Befehl kennen wir bereits.
Zeile 5: Hier wird die Variable "user" abgefangen, die wir in unserer URL angegeben haben
Zeile 6: Wie Zeile 5, nur mit der Variablen "text".
Hinweis: Einige von Euch werden jetzt bestimmt anmerken, dass man die Variablen und deren
Werte auch mit der globalen Variable $QUERY_STRING abfragen kann. Das ist auch soweit richtig.
Nur haben auch da einige Webhoster ihre eigenen Vorstellungen. Der Webhoster Strato, bei dem
ich bin, "mag" diese Variable nicht. Stattdessen soll man $_GET verwenden.
Die Zeilen 10-13 sollten soweit klar sein. Es wird eine Verbindung aufgebaut und die Daten werden
über eine SQL-Anweisung abgeschickt. Da wir jetzt aber ein weiteres Feld in der Datenbanktabelle
haben, müssen wir auch unsere "textausgabe_db.php" etwas modifizieren.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│7
Viel geändert haben wir da nicht. Interessant sind aber die Zeilen 21,23 und 24. Die Angabe "\n"
steht hier für einen Zeilenvorschub. Was der genau bewirkt, seht Ihr dann, wenn Eure 3dgsAnwendung gestartet wurde.
Logischerweise müssen wir auch in der C-Skript-Datei etwas ändern.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│8
OK, gehen wir die wdl-Datei Schritt-für-Schritt durch.
Zeile 04: Eine weitere Funktion wurde eingefügt. Was diese bewirkt, werden wir gleich noch
sehen.
Zeile 15: Ein String zum temporären abspeichern eines neuen Users.
Zeile 16: Ein String zum temporären abspeichern eines neuen Textes.
Zeile 17: In dieser Variable steht dann die komplette URL inkl. Datenanhang
Zeile 40: Wir müssen den String in eine url-konforme Zeichenkette umwandeln ( z.B. wird aus
einem Leerzeichen ein %20; aus einem ü wird ein %FC usw. )
Zeile 41: Gleiches gilt auch für diese Variable.
Die komplette URL sieht ohne die entsprechende Umwandlung ab Zeile 48 so aus:
http://www.darkware.de/3dgsmysql_tut/neuerdatensatz.php?user=Wicht&text=Schlümpfe
anschauen macht Spaß
Mit Umwandlung so:
http://www.darkware.de/3dgsmysql_tut/neuerdatensatz.php?user=Wicht&text=Schl%FCmpfe%20
anschauen%20macht%20Spa%DF
Ihr könnt das auch gerne überprüfen, indem Ihr die nicht umgewandelte URL in Euren Browser
eintippt. Der Browser wandelt diese Zeile ebenfalls um. Der Rest der wdl-Datei dürfte mittlerweile
verständlich sein. Mit HTTP_CREATE wird ein neuer Http-Client erzeugt. HTTP_GET ruft die URL auf.
Dann warten wir, bis der Webserver alles erledigt hat (HTTP_IsWorking). Zum Schluss wird noch
der HTTP-Client freigegeben. Die C-Skript-Zeilen zum abrufen von Daten haben sich derweil nicht
verändert. Nach dem Start unserer 3dgs-Anwendung sehen wir dieses Bild ...
Ein kontrollierender Blick via phpMyAdmin zeigt uns, dass die neuen Daten tatsächlich vorliegen ...
Das war's dann auch erstmal. Ich hoffe, Euch mit diesem Tutorial halbwegs geholfen zu haben.
Fehler, Anregungen, Kritiken usw. könnt Ihr gerne an info@darkware.de.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│9
Terrainerstellung mit Earthsculptor
Dieses Tutorial beschäftigt sich mit der Terrainerstellung
Earthsculptor [1] und dem Import in 3D Gamestudio.
mittels
dem
kostenlosen
Tool
Wichtig ist hierbei allerdings noch, dass dieses Verfahren nur ab der Commercial Version
funktioniert, da nur ab der Com Shader möglich sind.
Nachdem man Earthsculptor heruntergeladen, installiert und gestartet hat, klickt man auf File ->
New. Wir belassen es für den Moment bei den Standardeinstellungen. Nun sehen wir also folgendes
Bild (ich habe das kleine Fenster maximiert):
Wen der Nebel stört, der klickt im rechten Fenster auf „Fog" und schiebt dann den Regler „Far"
nach ganz rechts. Nun haben wir also ein sehr klares Bild.
In der Toolbox klicken wir nun auf den Button „Detail" (Das Karomuster).
Das Fenster auf der rechten Seite sieht nun so aus:
3D 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.
also, dass wir für unser Terrain bis zu 4 unterschiedliche Texturen verwenden können. Dabei gilt
folgende Regel: Eine Textur überlagert immer alle Texturen auf den Buttons links von ihr. D.h. Nr. 4
überlagert alles, Nr. 1 Nichts.
Klicken wir nun auf „Set Detail Texture" und wählen beispielsweise „longGrass.png" als Textur aus.
Das Terrain verändert sich sofort zu folgendem Bild:
Nun machen wir am besten damit weiter das Terrain ein wenig zu verformen. Dazu klicken wir in
der Toolbox auf das Symbol oben rechts „Terraform". Das Fenster auf der rechten Seite sieht nun
so aus:
Einfaches experimentieren mit den verschiedenen Tools ergibt meist schon recht schöne
Ergebnisse. Hierzu gebe ich keine genauere Anleitung, da sich die meisten Dinge beim
experimentieren erschließen. Die 3 Regler unter den Buttons geben den Radius des Tools, die
Stärke der Veränderung und die Stärke des Randes an.
Hier mal mein Beispiel Terrain nachdem ich einfach ein wenig mit den Tools herumgespielt habe:
3D 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 und
klicken auf „Set Detail Texture". Hier habe ich nun „cliff.png" gewählt, da ich nun die Berge
bemalen wollte. Nachdem die Textur ausgewählt ist können wir nun mit dem Bemalen des Terrains
beginnen. Die Regler sind ähnlich aufgebaut wie beim Verformen des Terrains.
Ein kurzes Zwischenergebnis:
Nun habe ich weitergemacht und auf die selbe Art und Weise die Detail-Textur 3 und 4 belegt und
auf das Terrain gemalt:
Klicken wir nun einmal auf den Pinsel „Paint" in der Toolbox.
Nun können wir im Farbauswahlfenster links eine Farbe wählen und auf das Terrain mahlen. Ich
habe grün gewählt und auf das Gras gemalt. Dadurch wirkt es saftiger und frischer:
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│12
Dies stellt nun auch das Endergebnis dar. Das Wasser ist hier nur ein Gimmick und kann nicht mit
exportiert werden. Klicken wir also nun auf File -> Save und speichern unser Terrain in einen
beliebigen (am besten leeren) Ordner ab. In diesem Ordner haben wir nun 5 Dateien:
„tutterrain.map" ist die Earthsculptor-Datei
„tutterrain.png" ist die Heightmap aus der MED
gleich das Terrain generieren wird
„tutterrain_c0.png" ist die Colormap. Hier ist das
saftige Grün unseres Grases gespeichert
„tutterrrain_d0.png" ist eine RGB-Blendmap. Diese Information dient dem Shader dazu die 4
Texturen richtig zu mischen.
„tutterrain_I0.png" ist die Shadowmap. Hier ist also die Beleuchtung gespeichert.
Nun müssen wir zuerst die Dateien umwandeln in andere Formate, damit MED damit etwas
anfangen kann. Das könnte etwas kompliziert werden, da man hier einige Umwege gehen muss.
Fangen wir mit der Datei „tutterrain.png" an. Diese wandeln wir am besten in eine .tga oder eine
.pcx Datei um .bmp würde zwar auch gehen, aber MED interpretiert diese bei mir nicht. Daher
wählen wir am besten TGS oder PCX. Das geht am einfachsten mit einem Tool wie dem
EasyGraphicsConverter [2].
Nun kommen wir zur Colormap, also die mit der Endung „_c0.png". Diese öffnen wir zuerst mit
Windows Paint und speichern sie als BMP Datei ab. Wie bereits erwähnt hat MED Probleme mit den
BMP Dateien und deswegen wandeln wir sie gleich mit dem EasyGraphicsConverter [2] in eine PCX
Datei um.
Mit der Blendmap „_d0.png" verfahren wir genauso. Also zuerst Paint -> Speichern als BMP ->
Umwandeln in eine PCX Datei.
Die Shadowmap „_I0.png" öffnen wir zuerst mit Photoshop oder Paint und stellen den Bildmodus
von Graustufe auf RGB um, sonst haben wir später Kanten bei den Schatten. Die Shadowmap
speichern wir diesmal gleich als PCX Datei.
WICHTIG! Die Blendmap und die Colormap nicht mit einem Programm wie Photoshop öffnen. Dann
Photoshop und Co. Interpretieren die Transparenz in den beiden Dateien falsch und beim Speichern
erhält man schlichtweg leere Dateien. Deswegen diese immer über Paint speichern, dann dieses
stellt keine Transparenzen dar.
So, nun haben wir also alle Dateien im PCX Format. Öffnen wir nun den MED. In MED klicken wir
nun auf File -> Import -> Import Terrain from Pic Dort wählen dann als Dateiformat PCX aus und
öffnen die „tutterrain.pcx" (also die Datei ohne Endung).
Im sich nun öffnenden Fenster stellen wir 100 x 100 Vertices ein.
3D 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
einem Klick auf „OK" sehen wir also nun unser in Earthsculptor erstelltes Terrain. Allerdings ist es
noch ein wenig zu flach. Wir klicken also auf das Skalierungstool und skalieren das Terrain ein
wenig in die Höhe, bis in etwa an das in Earthsculptor herankommt.
Nun öffnen wir das Skins-Menü (Edit -> Manage Skins)
Nun wählen wir den „Skin0" an und klicken auf „Skin Settings"
Wir machen einen Haken bei „Texture" und klicken auf „Texture File" und dann auf „...". Hier
wählen wir die Colormap aus. Also als Dateiformat PCX und dann die Datei mit der Endung
„_c0.pcx".
Dann klicken wir auf „New Skin" machen wieder einen Haken bei „Texture" und wählen diesmal die
RGBBlendmap aus („_d0.pcx").
Und das ganze wiederholen wir noch ein drittes Mal und wählen als letztes die Shadowmap
(„_I0.pcx") als Textur aus.
Das war's um Großen und Ganzen im MED schon. Wir speichern nun nur noch das Terrain als HMP
ab.
Wechseln wir nun zum WED. Nach einem Klick auf „New" wählen wir über Object -> Load Entity als
Dateiformat HMP aus und öffnen unser Terrain. Dann speichern wir den Level ab und klicken dann
auf File -> Map Properties. Hier klicken wir bei Script auf das Blatt Papier und wählen dann
„template" aus.
Jetzt können wir WED erstmal wieder schließen und öffnen die .WDL Datei, die nun in unserem
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│14
Ordner liegt. Wir bearbeiten sie so, dass sie wie folgt aussieht:
Bei „path" solltet ihr den Pfad zu eurem Projektordner angeben. Die Datei „terrain_multitex.wdl"
[3] kopiert ihr in euren Projektordner.
Nun müssen wir noch einmal ein bisschen mit Dateiformaten und Bildern jonglieren. Dazu müssen
wir zuerst einmal in Earthsculptor bei „Detail" mit der Maus über die Buttons gehen um die
Dateinamen der Texturen herauszufinden.
Nun müsst ihr diese Dateien (zu finden im Earthsculptor Ordner unter Textures) mit einem
Konvertierungsprogramm in das PCX oder BMP Format konvertieren. Desweiteren müsst ihr darauf
achten, ob die Texturen eine Größe von 256x256, 512x512 oder 1024x1024 haben.
Wenn nicht, müsst ihr sie noch skalieren, ansonsten gibt es nachher unschöne schwarze Ränder
auf dem Terrain. Die konvertieren Dateien legen wir ebenfalls in unseren Projektordner. Nun öffnen
wir die Datei „terrain_multitex.wdl" und gehen in die Zeilen 32 – 35.
Hier sind die Texturen angegeben, die nachher auf dem Terrain verwendet werden. Wir müssem
hier die Texturnamen von den eben konvertierten Texturen angeben. Dabei ist Button 1 in
Earthsculptor „tex3" und Button 4 „tex6".
Nun haben wir es fast geschafft. Nachdem wir die Datei abgespeichert haben, öffnen wir in WED
wieder unseren Level mit dem Terrain. Wir wählen es an und wählen mit einem Rechtsklick
„Properties" klicken auf das Behaviour Reiter und klicken dann auf das Ordner-Symbol. Hier wählen
wir dann Aktion „multi_rgb". Nun kompilieren wir den Level und bewundern unser Endergebnis:
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│15
Ich hoffe, dass ich hiermit einen Einblick sowohl in Earthsculptor als auch in das Importieren in 3D
Gamestudio geben konnte.
Sollte ihr Fragen haben, könnt ihr die gerne im Forum oder im Gästebuch meiner Webseite
loswerden.
Ein Dank geht an Loopix, der den Shader für das Terrain zur Verfügung gestellt hat als auch an
Nagashi, der den Shader für die Colormap modifiziert hat. DANKE!
die Downloadlinks:
[1] Earthsculptor
[2] EasyGraphicsConverter
[3] Terrain_multitex Shader
[4] Beispielprojekt
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│16
Die Sache mit der Motivation
Wenn ein Mann etwas ganz blödsinniges tut, so tut er es immer aus den edelsten Motiven(Oskar Wilde)
Es wurde schon viel über Projektmanagement, Teamarbeit und Planung geschrieben. All dies bringt
nicht viel, wenn keine oder kaum Motivation vorhanden ist, das geplante Projekt umzusetzen. In
diesem Artikel soll es nun um die Mannigfaltigkeit der Motivation gehen.
Hierbei muß klar sein: Nicht alles wirkt bei jedem. Aber es wird jeder in der Lage sein, aus diesem
Artikel etwas nützliches für sich herauszulesen.
Ich werde diesen Artikel ausnahmsweise und entgegen unserer Konventionen in der „Du" Form
schreiben, da es ein recht persönliches Thema ist. Ich denke, so kommen wir am ehesten weiter.
Vielleicht sollten wir erstmal beleuchten, was genau überhaupt Motivation ist. Wie entsteht der
starke Drang von innen heraus, Energie in eine bestimmte Sache zu stecken, die nicht extentiell
wichtig ist? Du mußt hier zwischen der inneren und der äußeren Motivation entscheiden.
Innere Motivation ist schwieriger zu erzeugen, aber nachhaltiger. Äußere Motivation ist schnell
„erheischt", aber verpufft auch ebenso schnell wieder. Ganz so einfach ist es natürlich nicht jedem Psychologen würden die Haare zu Berge stehen. Beide sind eng miteinander verknüpft und
beeinflussen sich. Du wirst sehen, nur die Mischung macht´s.
Motivation kommt von „Motiv" - ohne ein solches keine Motivation. Du kannst also nichts
erzwingen. Die gute Nachricht: Das brauchst und sollst Du auch gar nicht!
Die von uns allen gewünschte, innere Motivation braucht also einen Auslöser. Es können auch
mehrere sein, wichtig ist nur, daß dieser Auslöser eine Perspektive gibt, an die Du glauben kannst.
Hier entscheidet wiederum die eigene Skepsis und Begeisterungsfähigkeit.
Motivation ist aber gleichzeitig keine auf ein Projekt bezogene Gefühlsregung. Vielmehr ist
Motivation etwas allgemeines. Wenn Du in der Schule motiviert bist, trifft das auch auf viele andere
Bereiche des Lebens zu. Es gilt also, sich ein entsprechendes, „motivierendes" Umfeld zu schaffen.
Hier kann hoffentlich jeder auf einen gewissen Erfahrungsschatz zurückblicken. Gleichzeitig, bei
ersten Erfolgserlebnissen, fährt die Skepsis zurück - neue Horizonte tun sich auf.
Es gibt einige Patentrezepte, um die Motivation zu erhöhen. Du solltest Dir diejenigen raussuchen,
die den größten Erfolg versprechen.
Termin setzen
Wenn eine Sache drängt und sie Dir wichtig ist, solltest Du Dir einen festen Termin dafür setzen.
Dieser Artikel ist so entstanden. Wenn Du diesen Termin öffentlich machst, erhöht sich der Druck.
Termine dürfen nicht utopisch früh gewählt sein. Langes Überziehen des Termins bis zur Erfüllung
bewirken nämlich genau das Gegenteil - Demotivation. Darum solltest Du vorsichtig mit dieser
Methode umgehen.
Belohnungen
Belohnungen müssen gar nicht mal vorgesehen sein. Oftmals entstehen sie von alleine. Die vielen
Leser des Magazins sind mir z.B. Lohn genug. Allerdings kann es helfen, sich nach getaner Arbeit
etwas zu gönnen.
Kleine Ziele setzen
Auch dies ist eine Gratwanderung. Kleine Ziele dürfen nicht unbedeutend sein, sonst verkehrt sich
der Motivationseffekt ins Gegenteil. Kleine, aber ambitionierte Ziele helfen, eine große Sache
überschaubar zu machen.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│17
Bei Projektarbeit: Spielen!
Wenn Du mal wieder gar keine Lust hast, an einem Spiel weiterzumachen, so spiele es eine Weile.
Meist wird Dir dann bewußt, wie viel Arbeit schon drin steckt. Und es gehört schon eine ordentliche
Portion Melancholie dazu, dann nicht weiterzumachen. Auch hier gibt es zwei Seiten der Medaille:
Vielleicht fallen Dir lauter Baustellen auf, die Dich in diesem Moment überfordern. Du sagst Dir:
Wie soll ich das alles nur schaffen? Nun, bevor Du mit falschem Stolz und überzogenen
Erwartungen nicht weitermachst, schmeiße lieber einige Features raus. Du wirst sehen, wie der
Druck von Dir weicht. Das ist kein Grund, wieder unmotiviert zu werden. Im Gegenteil: Du beweißt
gesunden Menschenverstand, indem Du alte Meinungen und Vorurteile revidierst! Vor drei Jahren
warst Du vielleicht der Meinung, es muß ein MMORPG werden. Es ist nicht schlimm, wenn es doch
nur ein normales RPG wird.
Kommunikation
Viele User im Forum reden gerne - sei es über Chat, Mails oder PM. Tausche Dich mit ihnen aus.
Nimm das Zusammengehörigkeitsgefühl auf, sauge es ein! Sich gegenseitig zu motivieren ist zwar
nicht so nachhaltig wie die Eigenmotivation - aber es hängt zusammen. Durch konstruktive
Gespräche steigt Deine Laune ebenso wie Deine innere Motivation. Und zwar unterbewußt.
Motiviere Dich bewußt
Das ist vielleicht etwas hölzern ausgedrückt, darum gebe ich Dir ein Beispiel: Wenn Dir jemand ein
Kompliment macht - nimm es an. Sag´"Danke! Das ist nett von Dir!". Das hat viele positive
Effekte. Dein Selbstbewußtsein wird aufgebaut und Dein Gegenüber freut sich. Viel mehr, als wenn
Du in falscher Bescheidenheit sagst: „Na ja, so toll ist es auch nicht..."
Setz´ Dich nicht unter Druck
Wenn Du gar keine Lust hast, solltest Du keinen Termin setzen oder mit dem Kopf durch die Wand
wollen. Das ist okay und kein Grund zu verzweifeln. Motivation kann man nicht erzwingen. Man
kann sie sich nur „erfühlen". Umgebe Dich nicht mit Schwarzsehern. Sei Dir immer sicher, das alles
klappt - dann gibt es keine Gründe mehr verzweifelt zu sein. Du kannst es, Du machst es und Du
weißt es. Wo ist das Problem? Leg´ die Beine hoch, Du schaffst es doch sowieso!
Lass Dich nicht runterziehen
Wenn Du im Team arbeitest, dann steht und fällt die Motivation. Das ist ganz natürlich und kein
Prozess, den man so einfach aufhalten kann. Stattdessen solltest Du mit gutem Beispiel voran
gehen und signalisieren, daß Du an den Erfolg des Teams glaubst. In guten wie in schlechten
Zeiten. Wenn Du als Konstante fungierst, werden andere Teammitglieder davon mitgerissen.
Drohungen, Beschwerden und ähnliches helfen nicht. Das mußte ich selbst auch schon feststellen.
Häng´ das Projekt nicht am Team auf. Wenn Peter das getan hätten, wäre Mausgame nicht so weit,
wie es ist.
Einfach anfangen!
Den inneren Schweinehund zu überwinden ist nicht einfach. Ich mußte das auch tun, um diesen
Artikel zu schreiben. Aber siehe da: Es macht Spaß! Ich bin völlig überrascht von mir selbst! Das
kannst Du auch. Überrasche Dich immer mal wieder selbst, es ist fast so schön als wenn das
andere tun.
Nimm´ Dich nicht so ernst
Das kannst Du Dir nicht oft genug sagen. Wenn irgendwelche Steine im Weg liegen und Du
stolperst, lach drüber! Du kannst nur draus lernen und gestärkt daraus hervorgehen. Die
wenigsten Stolpersteine sollte man persönlich nehmen. Betrachte sie als Herausforderung,
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│18
vielleicht sogar als leicht tragischen Gag. Das nimmt ihnen die Härte und sorgt dafür, daß Du ihnen
nicht „ohnmächtig" gegenüberstehst.
Ich bin mir sicher, daß dieser Artikel einiges in Dir bewirken wird. Lass es raus!
Ich hätte auch schreiben können, daß ich HOFFE, daß dieser Artikel weiterhilft. Dem ist nicht so.
Stattdessen bin mir einfach sicher, daß er hilft. Basta. Ein schönes Gefühl. ;-)
Viel Spaß beim ausprobieren wünscht,
Torsten Fock
www.vulkanware.de
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│19
Einfache Physik durch Event Funktionen ohne
Newton und dergleichen
Ich möchte in diesem Tutorial mit Ihnen ein paar einfache Physik Bewegungen programmieren um
Objekte durch Berührung oder Beschuss zu bewegen.
Mann möge mir verzeihen wenn ich nicht die Befehle my.poligon = on und c_trace für
poligongenaue Abtastung verwende, aber da ich nur eine Sybex Version besitze sind diese Befehle
bei mir nicht möglich und ich möchte hier keine Skripte bzw. Befehle abdrucken die ich nicht
getestet habe.
Inhalt:
1. Vorstellung des Skriptes
2. Vorstellung der Aktion
2.1 Die Aktion "entity_1"
3. Vorstellung der Funktionen
3.1 Die Funktion "function ent_col_event1();"
// Event Funktion der Entity
3.2 Die Funktion "function physik_1();"
// Hauptfunktion der Entity
3.3 Die Funktion "function Max_Min_Berechnung();" // Grenzen der Bounding Box
3.4 Die Funktion "function Abstand_zum_Boden();" // Abstandsberechnung zum Boden
3.5 Die Funktion "function Abstand_Ecken();"
// Abstandsberechnung der Ecken
3.6 Die Funktion "function Schieflage();"
// Schieflage der Entity über Abgrund
3.7 Die Funktion "function Anziehungskraft();"
// Anziehungskraftberechnung der Entity
3.8 Die Funktion "function Drift();"
// Drift der Entity bei Schieflage
3.9 Die Funktion "function Kraftfaktor();"
// Kraftfaktorberechnung bei Berührung
3.10 Die Funktion "function Bewegung();"
// Bewegung der Entity
Bestimmte Variablen und die Handle der Entities werden im Skript in Arrays abgespeichert. Sollte
Ihnen die Verwendungsweise von Arrays nicht geläufig sein, können Sie in diversen Publikationen
und Tutorials mehr über diese Art der Speicherung erfahren. Im 3dgsMagazin No.2 finden Sie auch
ein Tutorial über die Benutzung von Arrays. Ich werde hier nicht im Einzelnen auf die
Funktionsweise von Arrays eingehen da dies den Rahmen hier sprengen würde.
Sämtliche Funktionen funktionieren auch mit dem Player der Template Skripte. Sie müssen nicht
erst einen eigenen Player-Skript schreiben.
1. Vorstellung des Skriptes
Zuerst einmal möchte ich Ihnen das Skript vorstellen. Danach werde ich im Einzelnen auf die
verschiedenen Aktionen und Funktionen eingehen um Ihnen die Funktionsweise näher zu bringen.
//////////////////////////////////////////
//// Definitionen für Bewegungskörper ////
//////////////////////////////////////////
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│20
define _gewicht,skill1;
define _entity_x,skill2;
define _entity_y,skill3;
define _entity_z,skill4;
define _MaxMin_x,skill8;
define _MaxMin_y,skill9;
define _MaxMin_z,skill10;
//define _speed,skill11;
// Noch nicht in Verwendung
//define _speed_x,skill11; // Noch nicht in Verwendung
//define _speed_y,skill12; // Noch nicht in Verwendung
//define _speed_z,skill13; // Noch nicht in Verwendung
define _dist_floorR,skill14;
define _dist_floorL,skill15;
define _dist_floorF,skill16;
define _dist_floorB,skill17;
define _dist_floorM,skill18;
define _ABSOLDIS,skill34;
define _ABSOLDIS_X,skill34;
define _ABSOLDIS_Y,skill35;
define _ABSOLDIS_Z,skill36;
define _floornormal1,skill37;
define _floornormal1_X,skill37;
define _floornormal1_Y,skill38;
define _floornormal1_Z,skill39;
define _f_drift,skill40;
define _move_x,skill41;
define _move_y,skill42;
define _force,skill43;
define _move_force,skill44;
define _Bewegung_Vert,skill45;
define _Bodenhöhe,skill46;
define ent_id,skill47;
define entity_id,skill48;
//////////////////////////////////////////////////////////
//// Variablen in Verbindung mit Templates ausblenden ////
//////////////////////////////////////////////////////////
var force[3] =0,0,0;
var friction;
var slopefac;
var gravity;
///////////////////
//// Variablen ////
///////////////////
var temp_1;
var temp_2;
var t;
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│21
var ent_nr;
/////////////////////////////
//// String und Entities ////
/////////////////////////////
entity* Koerper;
////////////////
//// Arrays ////
////////////////
var ent_array1[8000];
////////////////////
//// Funktionen ////
////////////////////
function ent_col_event1();
// Event Funktion der Entity
function Max_Min_Berechnung(); // Grenzen der Bounding Box
function Abstand_zum_Boden();
// Abstandsberechnung zum Boden
function Abstand_Ecken();
// Abstandsberechnung der Ecken der Entity zum Boden
function Schieflage();
// Schieflage der Entity über Abgrund
function Anziehungskraft();
// Anziehungskraftberechnung der Entity
function Drift();
// Drift der Entity bei Schieflage
function Kraftfaktor();
// Kraftfaktorberechnung bei Berührung der Entity
function Bewegung();
// Bewegung der Entity
//uses _Gewicht,_entity_x,_entity_y,_entity_z,
action entity_1
{
Koerper = my;
t += 10;
ent_nr = t;
my.ent_id = ent_nr;
my.fat = off;
my.narrow = on;
//my.passable = on;
my.push = 0;
if (my._gewicht == 0)
{my._gewicht = 10;}
my.event = ent_col_event1;
my.enable_sonar = on;
my.enable_shoot = on;
my.enable_block = on;
my.enable_entity = on;
my.enable_impact = on;
my.enable_push = on;
my.enable_click = on;
physik_1();
}
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│22
function ent_col_event1()
{
if(event_type == event_impact)
{
if(my == null){return;}
if(you == null){return;}
ent_nr = my.ent_id;
//// Koordinaten Trefferpunkt ////
ent_array1[ent_nr*10+0] = target[0];
ent_array1[ent_nr*10+1] = target[1];
ent_array1[ent_nr*10+2] = target[2];
//// Koordinaten auslösende Entity ////
ent_array1[ent_nr*10+3] = you.x;
ent_array1[ent_nr*10+4] = you.y;
ent_array1[ent_nr*10+5] = you.z;
//// Gewicht der Entity ////
if(you.skill1 == 0){temp = 10;}
if(player == you){temp = 10;}
ent_array1[ent_nr*10+6] = temp;
//// Geschwindigkeit der Entity ////
if(you.skill11 == 0){you.skill11 = 10;}
ent_array1[ent_nr*10+7] = you.skill11;
//// Winkel Aufprallrichtung ////
vec_diff(temp_1,target,you.x);
//// Abprallwinkel ////
vec_to_angle (temp,normal);
ent_array1[ent_nr*10+8] = temp.pan;
ent_array1[ent_nr*10+9] = temp.tilt;
//// Schiebende Kraft ////
my._force = ent_array1[ent_nr*10+6] * ent_array1[ent_nr*10+7];
}
if(event_type == event_shoot)
{
if(my == null){return;}
if(you == null){return;}
ent_nr = my.ent_id;
//// Koordinaten Trefferpunkt ////
ent_array1[ent_nr*10+0] = target[0];
ent_array1[ent_nr*10+1] = target[1];
ent_array1[ent_nr*10+2] = target[2];
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│23
//// Koordinaten auslösende Entity ////
ent_array1[ent_nr*10+3] = you.x;
ent_array1[ent_nr*10+4] = you.y;
ent_array1[ent_nr*10+5] = you.z;
//// Gewicht der Entity ////
temp = you.skill4;
if(player == you){temp = 10;}
ent_array1[ent_nr*10+6] = temp;
//// Geschwindigkeit der Entity ////
ent_array1[ent_nr*10+7] = you.skill5/2;
//// Winkel Aufprallrichtung ////
vec_diff(temp_1,target,you.x);
//// Abprallwinkel ////
vec_to_angle (temp,normal);
ent_array1[ent_nr*10+8] = temp.pan;
ent_array1[ent_nr*10+9] = temp.tilt;
//// Schiebende Kraft ////
my._force = ent_array1[ent_nr*10+6] * ent_array1[ent_nr*10+7];
}
if (event_type == event_click) // Noch nicht in Verwendung
{
koerper = me;
}
}
function physik_1()
{
Max_Min_Berechnung();
if(my._entity_x == 0)
{
my._entity_x = my._MaxMin_x;
}
if(my._entity_y == 0)
{
my._entity_y = my._MaxMin_y;
}
if(my._entity_z == 0)
{
my._entity_z = my._MaxMin_z;
}
while(1)
{
Abstand_zum_Boden();
Abstand_Ecken();
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│24
Anziehungskraft();
Schieflage();
Drift();
Kraftfaktor();
Bewegung();
wait(1);
}
}
function Max_Min_Berechnung()
{
my._MaxMin_x = (my.max_x - my.min_x);
my._MaxMin_y = (my.max_y - my.min_y);
my._MaxMin_z = (my.max_z - my.min_z);
}
function Abstand_zum_Boden()
{
vec_set (temp,nullvector);
vec_set(temp,my.x);
temp.z -=4000;
vec_set(temp_1,my.x);
temp_1.z = my.z - ((my._entity_z)/2);
trace_mode = ignore_me + ignore_sprites + ignore_models + scan_texture;
my._BODENHÖHE = trace(temp_1,temp);
// my._BODENHÖHE beinhaltet die Entfernung zum Boden
my._floornormal1_X = NORMAL.X;// my._floornormal auf die Normale des Bodens
richten
my._floornormal1_Y = NORMAL.Y;// my._floornormal auf die Normale des Bodens
richten
my._floornormal1_Z = NORMAL.Z;
}
function Abstand_Ecken()
{
//// Trace von Mitte nach unten ////
vec_set(temp.x,my.x);
temp.z = my.z - (my._entity_z)/2;
trace_mode = ignore_me + ignore_passable + ignore_passents;
my._dist_floorM = trace(temp.x,vector(temp.x,temp.y,temp.z-500));
//// Trace von links nach unten ////
vec_set(temp.x,vector(0,(my._entity_y/2),0));
vec_rotate(temp.x,vector(my.pan,0,0));
vec_add(temp.x,my.x);
temp.z = my.z - (my.max_z - my.min_z)/2;
trace_mode = ignore_me + ignore_passable + ignore_passents;
my._dist_floorL = trace(temp.x,vector(temp.x,temp.y,temp.z-500));
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│25
//// Trace von rechts nach unten ////
vec_set(temp.x,vector(0,-(my._entity_y/2),0));
vec_rotate(temp.x,vector(my.pan,0,0));
vec_add(temp.x,my.x);
temp.z = my.z - (my._entity_z)/2;
trace_mode = ignore_me + ignore_passable + ignore_passents;
my._dist_floorR = trace(temp.x,vector(temp.x,temp.y,temp.z-500));
//// Trace von vorne nach unten ////
vec_set(temp.x,vector((my._entity_x/2),0,0));
vec_rotate(temp.x,vector(my.pan,0,0));
vec_add(temp.x,my.x);
temp.z = my.z - (my._entity_z)/2;
trace_mode = ignore_me + ignore_passable + ignore_passents;
my._dist_floorF = trace(temp.x,vector(temp.x,temp.y,temp.z-500));
//// Trace von hinten nach unten ////
vec_set(temp.x,vector(-(my._entity_x/2),0,0));
vec_rotate(temp.x,vector(my.pan,0,0));
vec_add(temp.x,my.x);
temp.z = my.z - (my._entity_z)/2;
trace_mode = ignore_me + ignore_passable + ignore_passents;
my._dist_floorB = trace(temp.x,vector(temp.x,temp.y,temp.z-500));
}
function Schieflage()
{
temp = abs(my._dist_floorF - my._dist_floorB);
if(temp <= 1)
{
my.tilt = 0;
my._f_drift = 0;
}
temp = abs(my._dist_floorL - my._dist_floorR);
if(temp <= 1)
{
my.roll = 0;
my._f_drift = 0;
}
if (my._dist_floorM <= 2) {return;}
if (my._dist_floorM > 5 && my._dist_floorL > 5 && my._dist_floorR > 5 &&
my._dist_floorF > 5 && my._dist_floorB > 5)
{
return;
}
if (my._dist_floorL >= 5)
{
temp = atan(my._dist_floorL/(my._entity_y/2));
if(temp > abs(my.roll))
// Absolutberechnung da Roll negativ ist
{
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│26
my.roll -= 1 * time;
}
}
if (my._dist_floorR >= 5)
{
temp = atan(my._dist_floorR/(my._entity_y/2));
if(temp > my.roll)
{
my.roll += 1 * time;
}
}
if (my._dist_floorF >= 5)
{
temp = atan(my._dist_floorF/(my._entity_x/2));
if(temp > abs(my.tilt))
// Absolutberechnung da Tilt negativ ist
{
my.tilt -= 1 * time;
}
}
if (my._dist_floorB >= 5)
{
temp = atan(my._dist_floorB/(my._entity_x/2));
if(temp > my.tilt)
{
my.tilt += 1 * time;
}
}
}
function Anziehungskraft()
{
if (my._dist_floorM>5&&my._dist_floorL>5&& my._dist_floorR>5&&my._dist_floorF>5&&
my._dist_floorB > 5)
// in der Luft?
{
force.z = -5;
// Schwerkraft
friction = 0.1; // Luftwiederstand
// Geschwindigkeit vertikal
my._Bewegung_Vert = time*force.z + max(1-time*friction,0)*my._Bewegung_Vert;
my._absoldis_Z = time * my._Bewegung_Vert;
}
if (my._BODENHÖHE < 5 && my._BODENHÖHE > 0)
{
my._Bewegung_Vert = 0;
my._absoldis_Z = 0;
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│27
}
if (my._BODENHÖHE < 0 )
{
force.z = -0.5 * my._BODENHÖHE; // Boden-Elastizität
friction = 0.5; // Bodenreibung
// Geschwindigkeit vertikal
my._Bewegung_Vert = time*force.z + max(1-time*friction,0)*my._Bewegung_Vert;
my._absoldis_Z = time * my._Bewegung_Vert;
}
}
function Drift()
{
//// Kippbereich der Objekte ////
if (my._dist_floorM <= 2 && (my._move_x == 0 && my._move_y == 0)) {return;}
if(my.tilt != 0 || my._move_x != 0)
{
my._f_drift = my._gewicht * -sin(my.tilt);
my._move_x = my._f_drift * time + max(1-time*friction,0)*my._move_x;
my._absoldis_x = time * my._move_x;
}
if(my.roll != 0 || my._move_y != 0)
{
my._f_drift = my._gewicht * -sin(my.roll);
my._move_y = my._f_drift * time + max(1-time*friction,0)*my._move_y;
my._absoldis_y = time * my._move_y;
}
}
function Kraftfaktor()
{
if(my._f_drift != 0)
{
my._move_force = 0;
my._force = 0;
}
if(my._force > 0 || my._move_force > 0)
{
my._move_force = my._force * time + max(1-time*0.5,0)*my._move_force;
my._force = 0;
}
}
function Bewegung()
{
ent_nr = my.ent_id;
if(my._move_force > 0)
{
my._absoldis_X =
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│28
(cos(ent_array1[ent_nr*10+8])*(my._move_force/ent_array1[ent_nr*10+6]))*time;
my._absoldis_Y =
(sin(ent_array1[ent_nr*10+8])*(my._move_force/ent_array1[ent_nr*10+6]))*time;
}
if(my._move_force <= 0 && my._move_x == 0 && my._move_y == 0)
{
my._absoldis_X = 0;
my._absoldis_Y = 0;
}
move_mode = ignore_passable + activate_trigger + glide;
ent_move(nullvector,my._absoldis_X);
}
2. Vorstellung der Aktion
2.1 Die Aktion "action entity_1"
//uses _Gewicht,_entity_x,_entity_y,_entity_z,
action entity_1
{
Koerper = my; // Zuweisung nur zu Testzwecken
t += 10;
// Erhöhung der Array Variablen
ent_nr = t;
// Speichern der Erhöhung
my.ent_id = ent_nr;
my.fat = off;
// Speichern der Erhöhung in Entity Skill
// Abschalten der dicken Hülle
my.narrow = on; // Einschalten der dünnen Hülle
//my.passable = on;
if (my._gewicht == 0)
// Zuweisung eines Gewichtes bei Null
{my._gewicht = 10;}
my.event = ent_col_event1;
// Übergabe der Eventfunktion
my.enable_sonar = on;
// Sensibilisierung für Trace-Anweisung
my.enable_shoot = on;
// Sensibilisierung für Shoot-Event
my.enable_block = on;
// Sensibilisierung für Level-Kollisionen
my.enable_entity = on; // Sensibilisierung für Entity-Kollisionen
my.enable_impact = on; // Sensibilisierung für Entity-Kollisionen
my.enable_push = on;
// Sensibilisierung für Push-Event
my.enable_click = on;
// Sensibilisierung für Mausklick
physik_1();
// Sprung in Hauptfunktion
}
Die erste Zeile, die mit //uses beginnt gibt diejenigen Parameter an, die wir später im WED unter
Properties sehen, wenn wir der Entity die Aktion entity_1 zugewiesen haben. Als erstes wäre da
unser Gewicht. Durch das Gewicht der Entity wird bestimmt in wieweit sie sich bei Kollisionen von
ihrem ursprünglichen Platz wegbewegt. Die nächsten drei Angaben beziehen sich auf die
tatsächliche Grösse der Entity. Bezogen auf die gesamte X-, Y- und Z-Ausdehnung der Entity. Sie
können hier im WED die Werte eingeben. Sollten sie keine Angaben machen wird automatisch ein
Gewicht von 10 kg und die Ausdehnung der Bounding Box genommen.
So machen wir weiter mit der eigentlichen Aktion. Wir weisen der Entity den Namen Körper zu.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│29
Diese Zuweisung brauchen wir allerdings erst in einem späteren Tutorial, wenn es darum geht
diverse Kisten und dergleichen zu stapeln. Dann haben wir die Erhöhung der Array Variable. Ich
werde verschiedene Parameter, wie Kollisionspunkt, Kollisionsgeschwindigkeit und diverse andere
Angaben in einem Array speichern um Entity Skills zu sparen.
In den nächsten zwei Zeilen, ent_nr = t und my.ent_id = ent_nr speichere ich den Anfangsarray
jeder Entity in einem Entity Skill ab um später jeder Zeit wieder darauf zugreifen zu können. Dann
schalte ich die dicke Hülle der Entity ab und die dünne ein. Gefolgt von der vorher Besprochenen
Gewichtszuweisung von 10 kg wenn keine Eingabe im WED statt gefunden hat. Die Zuweisung der
Event Funktion, die Sensibilisierung für gewisse Event Aktionen und der darauffolgende Sprung zur
Hauptfunktion physik_1 beendet dann unsere Aktion entity_1.
3. Vorstellung der Funktionen
3.1 Die Funktion "ent_col_event1()"
function ent_col_event1()
{
if(event_type == event_impact)
{
if(my == null){return;}
if(you == null){return;}
ent_nr = my.ent_id;
//// Koordinaten Trefferpunkt ////
ent_array1[ent_nr*10+0] = target[0];
ent_array1[ent_nr*10+1] = target[1];
ent_array1[ent_nr*10+2] = target[2];
//// Koordinaten auslösende Entity ////
ent_array1[ent_nr*10+3] = you.x;
ent_array1[ent_nr*10+4] = you.y;
ent_array1[ent_nr*10+5] = you.z;
//// Gewicht der Entity ////
if(you.skill1 == 0){temp = 10;}
if(player == you){temp = 70;}
ent_array1[ent_nr*10+6] = temp;
//// Geschwindigkeit der Entity ////
if(you.skill11 == 0){you.skill11 = 10;}
ent_array1[ent_nr*10+7] = you.skill11;
//// Winkel Aufprallrichtung ////
// Wird noch nicht benötigt
vec_diff(temp_1,target,you.x);
//// Abprallwinkel ////
vec_to_angle (temp,normal);
ent_array1[ent_nr*10+8] = temp.pan;
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│30
ent_array1[ent_nr*10+9] = temp.tilt;
//// Schiebende Kraft ////
my._force = ent_array1[ent_nr*10+6] * ent_array1[ent_nr*10+7];
}
if(event_type == event_shoot)
{
if(my == null){return;}
if(you == null){return;}
ent_nr = my.ent_id;
//// Koordinaten Trefferpunkt ////
ent_array1[ent_nr*10+0] = target[0];
ent_array1[ent_nr*10+1] = target[1];
ent_array1[ent_nr*10+2] = target[2];
//// Koordinaten auslösende Entity ////
ent_array1[ent_nr*10+3] = you.x;
ent_array1[ent_nr*10+4] = you.y;
ent_array1[ent_nr*10+5] = you.z;
//// Gewicht der Entity ////
temp = you.skill4;
ent_array1[ent_nr*10+6] = temp;
//// Geschwindigkeit der Entity ////
ent_array1[ent_nr*10+7] = you.skill5/2;
//// Winkel Aufprallrichtung ////
vec_diff(temp_1,target,you.x);
//// Abprallwinkel ////
vec_to_angle (temp,normal);
ent_array1[ent_nr*10+8] = temp.pan;
ent_array1[ent_nr*10+9] = temp.tilt;
//// Schiebende Kraft ////
my._force = ent_array1[ent_nr*10+6] * ent_array1[ent_nr*10+7];
}
if (event_type == event_click) // Noch nicht in Verwendung
{
koerper = me;
}
}
Die erste If-Anweisung bezieht sich auf die Kollision mit einer anderen Entity. Gefolgt von zwei
Anweisungen die sich auf die my- und you-Entity beziehen, dort wird bei nicht vorhanden sein
einer der beiden Entities die Funktion sofort verlassen um etwaige Empty Pointer Fehlermeldungen
aus dem Weg zu gehen. Danach kommt der Aufruf der Array Nummer aus dem Entity Skill um die
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│31
ganzen speicherbaren Werte auch in den richtigen Array Bereich zu speichern und nicht etwa in
den Array Bereich einer anderen Entity die mit dieser Kollision garnichts zu tun hatte.
In den folgenden Array Variablen wird gespeichert, der Kollisionspunkt an der Entity, die X-, Y- und
Z-Werte der kollidierenden Entity, das Gewicht und die Geschwindigkeit der Entity.
Desweiteren die Winkelrichtung, die sich hier auf die Normale der Oberfläche beziehen. Und dann
noch die Berechnung der Kraft die auf die Entity wirkt. Die Kraft berechnet man ja bekanntlich, wie
jeder weiss der schon einmal Physik in der Schule gehabt hat, aus dem Produkt von Masse und
Beschleunigung.
my._force = ent_array1[ent_nr*10+6]*ent_array1[ent_nr*10+7]
Was bedeutet, meine Geschwindigkeit ist dein Gewicht mal deine Beschleunigung. In der IfAnweisung der shoot-Abfrage befinden sich die selben Berechnungen und Abfragen die wir vorher
schon besprochen haben. Nur die Gewichts- und Geschwindigkeitsangaben der Entity beziehen sich
hier auf andere Skill Werte. Für die Gewichtsberechnung ist hier der Skill4 und für die
Geschwindigkeitsberechnung der Skill5 der kollidierenden Entity zuständig.
Diese Skills finden auch in den Templates Verwendung. Deshalb habe ich sie auch hier verwendet
um Template Benutzer auch die Möglichkeit zu geben dieses Skript hier zu verwenden. Die letzte
If-Abfrage bezieht sich auf das Anklicken der Entity mit der linken Maustaste. Diese Abfrage findet
erst in einem späteren Tutorial Verwendung, wenn wir versuchen diverse Kisten oder Tonnen und
dergleichen zu stapeln.
3.2 Die Funktion "physik_1()"
function physik_1()
{
Max_Min_Berechnung();
if(my._entity_x == 0)
{
my._entity_x = my._MaxMin_x;
}
if(my._entity_y == 0)
{
my._entity_y = my._MaxMin_y;
}
if(my._entity_z == 0)
{
my._entity_z = my._MaxMin_z;
}
while(1)
{
Abstand_zum_Boden();
Abstand_Ecken();
Anziehungskraft();
Schieflage();
Drift();
Kraftfaktor();
Bewegung();
wait(1);
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│32
}
}
Die Hauptfunktion unserer Entity beinhaltet den Sprung in sämtliche andere Funktionen der Entity.
Ich wähle immer diesen Weg der Hauptfunktion und den Sprung in die Unterfunktionen da es mir
auf diesem Wege möglich ist eventuell bei bestimmten Aktionen verschiedene Funktionen der
Entity zu überspringen. Ich gehe hier nicht im einzelnen auf die verschiedenen Funktionssprünge
ein da wir die Funktionen noch genau besprechen werden.
Hier nur eine grobe Auflistung der Funktionen und für welche Berechnungen sie zuständig sind.
function Max_Min_Berechnung(); // Grenzen der Bounding Box
function Abstand_zum_Boden();
// Abstandsberechnung zum Boden
function Abstand_Ecken();
// Abstandsberechnung der Ecken der Entity zum Boden
function Anziehungskraft();
// Anziehungskraftberechnung der Entity
function Schieflage();
// Schieflage der Entity über Abgrund
function Drift();
// Drift der Entity bei Schieflage
function Kraftfaktor();
// Kraftfaktorberechnung bei Berührung der Entity
function Bewegung();
// Bewegung der Entity
Unterhalb des Funktionssprungs zur Max-Min Berechnung finden Sie die Zuweisung der Max-Min
Parameter in die Entity_X Skills, diese Zuweisung findet statt wenn im WED keine Angaben der
Ausdehnung der Entity gemacht werden.
3.3 Die Funktion "Max_Min_Berechnung()"
function Max_Min_Berechnung()
{
my._MaxMin_x = (my.max_x - my.min_x);
my._MaxMin_y = (my.max_y - my.min_y);
my._MaxMin_z = (my.max_z - my.min_z);
}
Hier berechnen wir die Grenzen der Bounding Box der Entity. Diese Berechnung könnte man sich
sparen, sie ist nicht unbedingt nötig. Aber dann müsste man jedesmal wenn man die Grösse
feststellen will immer wieder die Berechnung my.max-my.min durchführen. So spare ich mir das
und schreibe es in einen Entity Skill.
3.4 Die Funktion "Abstand_zum_Boden()"
function Abstand_zum_Boden()
{
vec_set (temp,nullvector);
vec_set(temp,my.x);
temp.z -=4000;
vec_set(temp_1,my.x);
temp_1.z = my.z - ((my._entity_z)/2);
trace_mode = ignore_me + ignore_sprites + ignore_models + scan_texture;
// my._BODENHÖHE beinhaltet die Entfernung zum Boden
my._BODENHÖHE = trace(temp_1,temp);
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│33
// my._floornormal auf die Normale des Bodens richten
my._floornormal1_X = NORMAL.X;
my._floornormal1_Y = NORMAL.Y;
my._floornormal1_Z = NORMAL.Z;
}
Zuerst Überschreiben wir den temp Vektor mit Null, danach weisen wir dem Vektor die X-, Y- und
Z-Werte der Entity zu und verändern den Z-Wert auf 4000 Quants unter der Entity.
Als nächstes schreiben wir die Koordinaten der Entity in den temp_1 Vektor und verändern den ZWert so das sich der Punkt genau an den Füßen der Entity befindet. Nun die Angabe des
trace_mode. Hier ignorieren wir die my Entity, Sprites, Modelle und scannen die Textur unterhalb
der Entity. Ich verwende hier bewusst nicht use_box da es beim scannen durch kleinere oder
größere Entities als die Bounding Box bzw. die Hülle zu ungewünschten und fehlerhaften Effekten
kommen kann. Das Ergebnis des Trace wird dann in den Skill my._Bodenhöhe geschrieben. Die
letzten drei Zeilen beziehen sich noch auf Winkel des Bodens unterhalb der Entity, also die Normale
des Bodens.
3.5 Die Funktion "Abstand_Ecken()"
function Abstand_Ecken()
{
//// Trace von Mitte nach unten ////
vec_set(temp.x,my.x);
temp.z = my.z - (my._entity_z)/2;
trace_mode = ignore_me + ignore_passable + ignore_passents;
my._dist_floorM = trace(temp.x,vector(temp.x,temp.y,temp.z-500));
//// Trace von links nach unten ////
vec_set(temp.x,vector(0,(my._entity_y/2),0));
vec_rotate(temp.x,vector(my.pan,0,0));
vec_add(temp.x,my.x);
temp.z = my.z - (my.max_z - my.min_z)/2;
trace_mode = ignore_me + ignore_passable + ignore_passents;
my._dist_floorL = trace(temp.x,vector(temp.x,temp.y,temp.z-500));
//// Trace von rechts nach unten ////
vec_set(temp.x,vector(0,-(my._entity_y/2),0));
vec_rotate(temp.x,vector(my.pan,0,0));
vec_add(temp.x,my.x);
temp.z = my.z - (my._entity_z)/2;
trace_mode = ignore_me + ignore_passable + ignore_passents;
my._dist_floorR = trace(temp.x,vector(temp.x,temp.y,temp.z-500));
//// Trace von vorne nach unten ////
vec_set(temp.x,vector((my._entity_x/2),0,0));
vec_rotate(temp.x,vector(my.pan,0,0));
vec_add(temp.x,my.x);
temp.z = my.z - (my._entity_z)/2;
trace_mode = ignore_me + ignore_passable + ignore_passents;
my._dist_floorF = trace(temp.x,vector(temp.x,temp.y,temp.z-500));
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│34
//// Trace von hinten nach unten ////
vec_set(temp.x,vector(-(my._entity_x/2),0,0));
vec_rotate(temp.x,vector(my.pan,0,0));
vec_add(temp.x,my.x);
temp.z = my.z - (my._entity_z)/2;
trace_mode = ignore_me + ignore_passable + ignore_passents;
my._dist_floorB = trace(temp.x,vector(temp.x,temp.y,temp.z-500));
}
In dieser Funktion wird der Abstand von jeder Ecke der Entity zum Boden gemessen. Ich werde das
ganze an Hand des Trace von links nach unten erklären. Die anderen Anweisungen basieren auf
dem gleichen Prinzip. in der ersten Zeile speichern wir in die temp-Variable einen Vektor dessen Xund Z-Wert null sind und nur sein Y-Wert die Größe der halben Entity-Breite aufweist. Diesen
Vektor drehen wir nun durch vec_rotate in Bezug auf den Pan-Wert der Entity. Nach der Drehung
haben wir einen Vektor der 90 Grad nach Links steht mit der Länge der halben Entity. So, jetzt
haben wir die Richtung des Vektors festgelegt. Was jetzt noch fehlt ist die genaue Lage, denn bis
jetzt sitzt der Vektor noch auf dem Nullpunkt des WED. Um den Vektor in die richtige Endlage zu
verschieben verwenden wir den Befehl vec_add. Wir addieren nun zu unserem Vektor den Vektor
der Entity und schon sitzt der Punkt den wir haben wollten 90 Grad links neben unsere Entity. Nun
noch den Z-Wert an den unteren Punkt der Entity verschieben und schon haben wir unseren ersten
Tracepunkt festgelegt. Im trace_mode ignorieren wir diesmal wieder die my-Entity, Blocks die das
passable-Flag gesetzt haben und Modelle und Sprites die auf passable gesetzt sind. Dann wird der
Trace von unserem linken Punkt in eine Tiefe von 500 Quants ausgeführt und in den Skill
my._dist_floorL übertragen. Das ganze führen wir von allen vier seitlichen Punkten und von der
Mitte der Entity aus.
3.6 Die Funktion "Schieflage()"
function Schieflage()
{
temp = abs(my._dist_floorF - my._dist_floorB);
if(temp <= 1)
{
my.tilt = 0;
my._f_drift = 0;
}
temp = abs(my._dist_floorL - my._dist_floorR);
if(temp <= 1)
{
my.roll = 0;
my._f_drift = 0;
}
if (my._dist_floorM <= 2) {return;}
if (my._dist_floorM > 5 && my._dist_floorL > 5 && my._dist_floorR > 5
&& my._dist_floorF > 5 && my._dist_floorB > 5)
{
return;
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│35
}
if (my._dist_floorL >= 5)
{
temp = atan(my._dist_floorL/(my._entity_y/2));
if(temp > abs(my.roll))
// Absolutberechnung da Roll negativ ist
{
my.roll -= 1 * time;
}
}
if (my._dist_floorR >= 5)
{
temp = atan(my._dist_floorR/(my._entity_y/2));
if(temp > my.roll)
{
my.roll += 1 * time;
}
}
if (my._dist_floorF >= 5)
{
temp = atan(my._dist_floorF/(my._entity_x/2));
if(temp > abs(my.tilt))
// Absolutberechnung da Tilt negativ ist
{
my.tilt -= 1 * time;
}
}
if (my._dist_floorB >= 5)
{
temp = atan(my._dist_floorB/(my._entity_x/2));
if(temp > my.tilt)
{
my.tilt += 1 * time;
}
}
}
Die Funktion Schieflage ist dafür da um Objekte, wenn sie über einen Abgrund geschoben werden
und sich ihr Schwerpunkt verlagert, abrutschen zu lassen und sie nicht erst mit der
Anziehungskraft in Berührung kommen wenn sie komplett darüber hinweg geschoben wurden.
Als erstes die Berechnung der Deaktivierung der Schieflage und der Drift. Wenn der Bodenabstand
zwischen den zwei Punkten der Entity, z.b. der Absolutwert der Differenz des äusseren linken und
rechten Punktes der Entity, kleiner als 1 Quant ist werden der Tilt-Winkel der Entity und der
Driftfaktor auf Null gesetzt. Die gleiche Berechnung findet für den vorderen und den hinteren Punkt
statt. Danach kommen zwei Einträge, die die Funktion beenden. Einmal die Abfrage vom mittleren
Punkt zum Boden. Wenn der Abstand kleiner 2 Quants ist wird die Funktion beendet.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│36
Das ist klar denn in diesem Fall wäre der Schwerpunkt nicht über dem Abgrund und im zweiten Fall
die Abfrage alles Punkte der Entity nach unten, denn da würde ja der freie Fall nach unten
vorliegen was eine seitliche Drift auch beenden würde. Als nächste folgt wieder die Abfrage der
einzelnen Aussenpunkte der Entity ob diese mehr als 5 Quants vom Boden entfernt sind und die
darauffolgende Berechnung des Neigungswinkels mit Hilfe des Arcustangens.
Mit temp = atan(my._dist_floorL/(my._entity_y/2)) berechnen wir den Neigungswinkel der Entity.
Neigungswinkel = Arcustangens(Abstand zum Boden Links / Halbe Entity Breite). Dies ist also der
Neigungswinkel, den die Entity erreichen muss wenn sie über einen Abgrund geschoben wird. Es
folgt nun die Abfrage ob der Neigungswinkel grösser als der momentane Winkel der Entity ist.
Sollte das der Fall sein wird zyklisch der Wert 1 zum Winkel der Entity dazu addiert. Die
Berechnung der Neigungswinkel der anderen 4 Eckpunkte findet auf die selbe Art statt.
3.7 Die Funktion "Anziehungskraft()"
function Anziehungskraft()
{
// in der Luft?
if (my._dist_floorM > 5 && my._dist_floorL > 5 && my._dist_floorR > 5 &&
my._dist_floorF > 5 && my._dist_floorB > 5)
{
force.z = -5;
// Schwerkraft
friction = 0.1; // Luftreibung
// Geschwindigkeit vertikal
my._Bewegung_Vert = time*force.z + max(1-time*friction,0)*my._Bewegung_Vert;
my._absoldis_Z = time * my._Bewegung_Vert;
}
// Bis zu 5 Quant über dem Boden
if (my._BODENHÖHE < 5 && my._BODENHÖHE > 0)
{
my._Bewegung_Vert = 0;
my._absoldis_Z = 0;
}
// Eintauchen im Boden
if (my._BODENHÖHE < 0 )
{
force.z = -0.5 * my._BODENHÖHE; // Boden-Elastizität
friction = 0.5; // Bodenreibung
// Geschwindigkeit vertikal
my._Bewegung_Vert = time*force.z + max(1-time*friction,0)*my._Bewegung_Vert;
my._absoldis_Z = time * my._Bewegung_Vert;
}
}
Kümmern wir uns nun um die Anziehungskraft, die ja bekanntlich auf jeden Körper wirkt. Als
erstes Testen wir ob sich die Entity in der Luft befindet. Das überprüfen wir indem wir feststellen ob
sich jeder Aussenpunkt mindestens 5 Quants über dem Boden befindet. Ist dies der Fall übergeben
wir die Parameter der Schwerkraft und der Luftreibung und berechnen damit eine negative, da die
Schwerkraft den Wert -5 hat, vertikale Bewegung.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│37
Die Berechnung, Strecke = Zeit * Beschleunigung, ergibt nun die absolute Z-Distanz der Entity. Im
nachfolgenden Schritt, 5 Quant über dem Boden, gebe ich der Entity die Freiheit nicht genau auf
dem Boden aufzusitzen sondern bis zu 5 Quant darüber zu bleiben. Der nächste Funktionsschritt
bezieht sich auf das Eintauchen im Boden. Hier wird die Entity wieder aus dem Boden
herausgezogen. Der Grundwert der Geschwindigkeit ist hier wieder negativ (force.z = -0.5), was
bedeuten würde das wir bei der späteren Berechnung nocheinmal eine negative vertikale
Bewegung hätten. Das ganze bekommt jedoch einen positiven Wert da der force.z-Wert mit der
Bodenhöhe multipliziert wird und die ist sobald wir im Boden eintauchen negativ. Da bekanntlich
Minus * Minus = Plus ist werden wir im Laufe der nachfolgenden Berechnungen durch den jetzt
positiven force.z-Wert wieder aus dem Boden herausgedrückt.
3.8 Die Funktion "Drift()"
function Drift()
{
//// Kippbereich der Objekte ////
if (my._dist_floorM <= 2 && (my._move_x == 0 && my._move_y == 0)) {return;}
if(my.tilt != 0 || my._move_x != 0)
{
my._f_drift = 1 * -sin(my.tilt);
my._move_x = my._f_drift * time + max(1-time*friction,0)*my._move_x;
my._absoldis_x = time * my._move_x;
}
if(my.roll != 0 || my._move_y != 0)
{
my._f_drift = 1 * -sin(my.roll);
my._move_y = my._f_drift * time + max(1-time*friction,0)*my._move_y;
my._absoldis_y = time * my._move_y;
}
}
In dieser Funktion berechnen wir die Drift der Objekte bei Schräglage. Die Funktion wird verlassen,
wenn der Abstand zum Boden von der Mitte der Entity kleiner gleich 2 Quant, die Driftbewegung in
X-Richtung und die Driftbewegung in Y-Richtung gleich 0 sind. Als nächstes folgt die Abfrage ob
sich die Entity schon in einer Driftbewegung befindet und wenn ja wird die Berechnung der Drift in
die jeweilige Richtung fortgesetzt. Diese Berechnungen werden sowohl für den Tilt- als auch für
den Roll-Winkel durchgeführt.
3.9 Die Funktion "Kraftfaktor()"
function Kraftfaktor()
{
if(my._f_drift != 0)
{
my._move_force = 0;
// Geschwindigkeit durch die Kraft
my._force = 0;
// Kraftfaktor
}
if(my._force > 0 || my._move_force > 0)
{
my._move_force = my._force * time + max(1-time*0.5,0)*my._move_force;
my._force = 0;
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│38
}
}
Wenn Sie sich noch erinnern haben wir unseren Kraftfaktor my._force schon am Anfang des
Tutorials kennen gelernt und zwar in der Berechnung:
//// Schiebende Kraft ////
my._force = ent_array1[ent_nr*10+6] * ent_array1[ent_nr*10+7];
Dies ist die Kollisionskraft die uns von den Objekten die mit der Entity zusammen gestossen sind
mitgegeben wurde. In der ersten If-Anweisung wird überprüft ob im Moment eine Driftbewegung
ausgeführt wird. Sollte dies der Fall sein werden der Kraftfaktor und die daraus resultierende
Geschwindigkeit auf 0 gesetzt. Die nächste If-Abfrage überprüft ob noch eine Kraft auf die Entity
wirkt und führt bei einem positivem Ergebnis die Berechnung der schiebenden Kraft fort und setzt
den Kraftfaktor auf 0. Das Rücksetzen des Kraftfaktors bewirkt, dass nach dem Erreichen der
maximalen Geschwindigkeit die Entity wieder bis auf 0 abgebremst wird. Was in der Realität für
Kraftbewegungen genauso zutrifft.
3.10 Die Funktion "Bewegung()"
function Bewegung()
{
ent_nr = my.ent_id;
if(my._move_force > 0)
{
my._absoldis_X = (cos(ent_array1[ent_nr*10+8])*(my._move_force/my._gewicht))*time;
my._absoldis_Y = (sin(ent_array1[ent_nr*10+8])*(my._move_force/my._gewicht))*time;
}
if(my._move_force <= 0 && my._move_x == 0 && my._move_y == 0)
{
my._absoldis_X = 0;
my._absoldis_Y = 0;
}
move_mode = ignore_passable + activate_trigger + glide;
ent_move(nullvector,my._absoldis_X);
}
Nun kommen wir zur letzten Funktion dieses Skriptes. Hier findet die Bewegung der Entity statt.
Zuert lesen wir wieder die Array Nummer, ent_nr, aus unserem gespeicherten Entity Skill aus. Als
nächstes überprüfen wir ob noch eine Kraftbewegung aktiv ist um damit die Entity mit ihren
Absolutwerten zu verschieben. Die darauffolgenden zwei Zeilen beinhalten die Distanzberechnung
in Absolutwerten. Das bedeutet das die Entity nicht relativ zu der Ausrichtung ihres Pan-Wertes
bewegt wird. Ich möchte dies kurz an Hand des absoluten X-Wertes erklären. In unserem Array
(ent_nr*10+8) steht der Winkel in dessen Richtung die Entity bewegt wird. Mit der
mathematischen Berechnung,
Ankathete = cos(Winkel) * Hypothenuse
legen wir die X-Entfernung der Entity fest. Wobei die Ankathete die X-Verschiebung, der Winkel,
der eingetragener Kollisionswinkel und die Hypothenuse die Geschwindigkeit durch das Gewicht der
Entity multipliziert mit der Zeit ist. Ich diffidiere hier die Geschwindigkeit durch das Gewicht, da die
Bewegung der Entity abhängig von ihrem Gewicht sein soll. Je schwerer desto kürzer der
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│39
Bewegungsweg. Genau dieselbe Berechnung führen wir bei der Y-Verschiebung aus. In der
nächsten If-Anweisung überprüfen wir ob noch eine Verschiebung der Entity durch die Drift oder
die Kraftbewegung ausgeführt wird uns setzen bei keiner ausübenden Bewegung die X- und YVerschiebung auf 0. Gefolgt wird das Ganze von der Angabe des move_mode und der
anschliessenden Bewegung der Entity mit den Absolutwerten.
Ich hoffe ich konnte Ihnen einen kleinen Einblick in die Welt der einfachen Physik vermitteln. In
einem der nächsten Tutorials werden ich noch die Bewegung auf schiefen Ebenen, Rotation, das
Hochheben und Stapeln von Fässern oder Kisten basierend auf diesem Physik-Skript besprechen.
Für Fragen und Anregungen stehe ich Ihnen gerne unter meiner E-Mail Adr.
aras_game@chefmail.de
MFG
ARAS14
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│40
Zum Kugeln
oder: Der einfache weg zum nahtlosen UV-Gitter
Willkommen zu meinem ersten Tutorial über Mapping und 3d-Modelle. Auf zwei Seiten werden Sie
lernen, wie einfach es ist, eines der schwersten Objekte im Raum auf eine Fläche abzuwickeln und
mit einer Textur zu versehen.
Vorher sollte Ihnen aber klar sein, dass diese, wie jede andere Methode auch, ihre Probleme hat
und keineswegs der ultimative Weg zum Glück ist. So eignet sich die Methode gut für NebelSpheres oder Asteroiden, weniger aber für Himmelskörper wie Globen oder Planeten, bei denen es
auf die möglichst verzerrungsfreie Darstellung der Textur ankommt. Hier bleibt Ihnen wohl
vorläufig nichts Anderes übrig, als Ihre Texturen von Hand einzupassen.
Wir beginnen zunächst mit einem Ausgangsbild.
Es ist weder kachelbar, noch für Kugeln angepasst. Für die Umwandlung des Bildes benötigen wir
zwei kostenlose Plugins für Grafikprogramme wie beispielsweise Photoshop oder Paint Shop Pro,
aber auch kostenlose Programme werden unterstützt.
Besuchen Sie http://www.richardrosenman.com/software/downloads/, hier finden Sie auch die
volle Liste der unterstützen Programme. Die benötigten Plugins heißen „Spherical Mapping
Corrector" und „Tiler", laden Sie sie herunter und entpacken Sie die Zip-Archive in den Plugin-
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│41
Ordner Ihres Malprogrammes.
1) Laden Sie das Bild in Ihr Grafikprogramm.
2) Führen Sie das Plugin „Spherical Mapping Corrector" aus.
3) Nutzen Sie das Plugin „Tiler", um die rechten und linken Kanten nahtlos ineinander über gehen
zu lassen, Sie können die Werte des Screenshots als Referenz nehmen:
4) Wickeln Sie Ihre Kugel mit einem Sphere-Mapping- Algorithmus in Ihrem 3d-Programm aus, so
dass das Gitter wie im folgenden Bild aussieht:
Sowohl Cinema4d und 3ds Max, als auch kostenlose bzw. kostengünstige Tools wie Wings3d,
UltimateUnwrap/LithUnwrap oder Blender werden mit einem Knopfdruck damit fertig. Texturieren
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│42
Sie Ihre Kugel mit der soeben erstellten Map et voilà. Keine Pole, keine Nähte.
Ein Wermutstropfen bleibt jedoch, streckenweise ist die Textur leicht verzerrt, somit sollte Ihre Map
eine vernünftige Auflösung besitzen und keine Beschriftungen oder Ähnliches beinhalten.
Felix Caffier
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│43
Jetzt gibt's auf die Ohren! Soundeffekte Teil 3
Herzlich willkommen zum dritten Teil des Soundeffekt Tutorials.
Heute werden wir einen verwendbaren Sound designen, einen Schuss, um genau zu sein. Dieser
hier passt am ehesten zu einer Maschinenpistole oder ähnlichem. Sie werden erfahren wie Sie den
Sound erstellen, ihn bearbeiten und in die Engine einfügen. Und Sie werden vielleicht überrascht
sein, wie simpel die Grundsätze mal wieder sind.
Zusätzlich gibt es einige Tipps und Tricks zur Einbindung von Sounds in Gamestudio.
Um dieses Tutorial durcharbeiten zu können benötigen Sie den „Soundforum Synth V 1.0", den Sie
hier erhalten:
http://www1.keyboards.de/soundforum.htm#dersynthesizer
WARNUNG: Softwaresynthesizer können jeden möglichen und unmöglichen Ton
erzeugen. Auch solche, die jenseits der Leistungsfähigkeit Ihrer Lautsprecher liegen!
Seien Sie vorsichtig, beginnen Sie mit niedrigen Lautstärken und verwenden Sie bitte
keine Kopfhörer. Der Schalldruck kann ungeahnte Ausmaße annehmen und zu
Hörschäden führen! Ich übernehme keine Verantwortung für materielle und / oder
körperliche Schäden die aus der Benutzung dieses Tutorials resultieren.
Starten Sie den Soundforum Synth und wählen Sie die Voreinstellung „Basic Noise".
Wenn Sie einige Tasten drücken, können Sie in der Tat ein Rauschen hören. Nun wollen wir daraus
einen Schuss generieren.
Um Sie nicht zu sehr zu verwirren, stellen wir erstmal alle Hüllkurvenregler auf null, ausgenommen
die „Decay" Regler, die kommen auf 20.
Schauen Sie sich das Bild dazu an:
In der Filter Sektion stellen Sie bitte „Cutoff" auf 70 ein und „Env" auf 40. Es werden also nur
tiefere Frequenzen durchgelassen, wobei die Hüllkurve des Filters auch etwas Einfluss hat.
„K-Track" stellen Sie bitte auf Null, um unerwünschte Tonhöheneinflüsse durch das Keyboard
auszuschließen.
Nun müssen Sie etwas lauter machen, entweder am „Level" Regler des Synth oder an Ihren Boxen.
Der Grund hierfür: Der Filter lässt nur noch tiefe Frequenzen durch. Da diese im hellen Rauschen
nur sehr leise vorhanden sind, müssen
Sie sie verstärken.
Was da so ein wenig nach klopfen auf Holz klingt, ist Ihr Ausgangsmaterial für den Schuss!
Nun wird es Zeit für eine bittere Pille: Der Soundforum Synth kann keine Sounds exportieren.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│44
Wenn sie über die Soundkarte abgenommen werden, klingen sie sehr verrauscht.
Um Ihnen dennoch die Möglichkeit zu geben, den Sound fertig zu machen, habe ich mit Reaktor4
den gleichen Sound erstellt und hochgeladen. Sie finden sämtliche Dateien hier:
http://home.arcor.de/braindamaged/soundtut3.zip
Zusätzlich brauchen Sie noch das folgende Programm: http://www.audacity.de
Dieses Programm dient zur Bearbeitung von Audiodaten. Genau daß, was Sie brauchen. Und
obendrein kostet es keinen Cent!
Stellen Sie sicher, daß ein Ogg-Codec auf ihrem System installiert ist.
Nach dem starten von Audacity und öffnen der Datei „shot1.ogg" bietet sich Ihnen folgendes Bild:
Der Sound ist immer noch recht leise und liegt in Stereo vor. Das ist nicht unbedingt gut. Für einen
Schuß lohnt es sich nicht, auf Stereo zu pochen. Mono reicht hier völlig aus.
Klicken Sie hierzu links neben der oberen „Tonspur" auf den Pfeil bei „shot1". Nun öffnet sich ein
kleines Kontextmenü, in dem Sie „Stereotonspur aufteilen" wählen.
Mit einem Klick auf das Kreuz der zweiten Tonspur löschen Sie diese. Nun ist nur noch eine übrig,
die Sie über das Kontextmenü auf „Mono" setzen können.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│45
Wählen Sie „Bearbeiten" --> „Auswählen" --> „Alles". Dies ist nötig, um den Sound lauter zu
machen.
Wählen Sie nun „Effekt" --> „Verstärken":
Klicken Sie auf „Ok". Nun ist der Sound wesentlich lauter. Wählen Sie mit der Maus den stillen
Bereich vor dem Sound aus und löschen Sie ihn mit „Bearbeiten" --> „Auswahl löschen". Mit der
stillen Stelle nach dem Sound verfahren Sie genauso. Nun ist der Sound auch schön handlich:
Leider klingt er noch nicht überzeugend. Um ihm etwas mehr punch zu geben, schauen Sie mal
unter „Effekt" --> „Tonhöhe (Pitch) ändern":
Wählen Sie einen Wert von 40%. Wenn Sie damit schon zufrieden sind, können Sie den Sound als
Ogg oder Wav exportieren. Ich rate Ihnen zu Ogg - sie sind wesentlich kleiner und kosten keine
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│46
Lizenzgebühren wie mp3. Das dazu ein extra Codec nötig ist, kann man verschmerzen.
Spielen wir ein wenig mit dem Kompressor herum:
Markieren Sie alles wenn dies nicht schon der Fall ist. Gehen Sie auf "Effekte" --> "Kompressor".
Es ist wichtig daß Sie die Ansprechzeit auf 0,1 Sekunden stellen. Ansonsten spricht der Effekt zu
spät an.
Lassen Sie sich nicht täuschen, sollten Sie kaum einen Unterschied hören beim experimentieren
mit diesem Effekt.
In der Wiederholung als MG-Sound wirken sich auch kleine Änderungen aus.
Starten Sie „shot.exe" und schauen Sie sich die wdl Datei an, um einen Eindruck davon zu
bekommen, wie man den Sound einsetzen könnte. Vor allem mit der „snd_tune" Anweisung kann
man einiges anstellen.
Ich hoffe, es hat Ihnen Spass gemacht. Natürlich kann es dieser Sound nicht mit aktuellen Sounds
aus der Spielebranche aufnehmen. Hierfür ist der Soundforum Synth nicht flexibel genug. Aber
lassen Sie sich gesagt sein: Auch die Profis kochen nur mit Wasser. ;-)
Letztlich wird nahezu jede Explosion und jeder Schuss aus Rauschen generiert. Ob es von einem
Oszillator produziert wurde oder ursprünglich ein ganz anderes Geräusch (im wahrsten Sinne) war,
ist nur eine Möglichkeit der Variation.
Das nächste Mal werden wir uns mit der Verfremdung und Veränderung von bereits vorhandenen
Sounds mit Audacity beschäftigen. Außerdem lernen Sie, wie Sie mit vertretbarem Aufwand gute
Aufnahmen erstellen können.
Ich wünsche Ihnen viel Spass bis dahin, Torsten Fock
www.vulkanware.de
Tipps und Tricks zur Einbindung
snd_tune(handle, Volume, Freq, balance);
Diese Anweisung hilft Ihnen, etwas Zufall in die Sache zu bringen oder Motorensounds zu steuern.
Schauen Sie sich das folgende, kurze Script an:
function play_crossfire
{
var sndhandle;
sndhandle = snd_play(crossfire_snd, 100, 0);
temp = random(20)+90;
snd_tune(sndhandle, temp, temp, 0);
}
Hier wird direkt nachdem der Sound angestossen wurde seine Frequenz (und die
Abspielgeschwindigkeit!) sowie die Lautstärke zufällig geändert. Dies eignet sich sehr gut für
Kreuzfeuer, Querschläger, Explosionen u.s.w.
Gehsounds zur Animation synchronisieren:
-skill1 muß auf 1 gesetzt werden, wenn die Entity läuft.
-skill2 ist in diesem Beispiel der animationszähler der Figur 0...100%.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│47
function char_sounds
{
while(me)
{
if(my.skill1 == 1) // ich laufe
{
snd_play(walk_1_snd, 100, 0);
while(my.skill2 < 50){wait(1);}
snd_play(walk_1_snd, 100, 0);
while(my.skill2 > 0){wait(1);}
}
wait(1);
}
}
Motorengeräusche:
freq ist eine Variable, die von der Geschwindigkeit des Wagens beeinflußt wird.
Wenn Sie es realer haben wollen, müssen Sie in ein aufwändigeres Script anfertigen, daß sich mit
der "Drehzahl" der Reifen und dem Zustand der Gangschaltung beschäftigt.
function tune_sound
{
var soundhandle;
soundhandle = snd_loop(engine_snd, 100, 0) // oder ent_playloop benutzen, je nach Bedarf
while(me)
{
snd_tune(soundhandle, 0, freq, 0);
wait(1 ;
}
}
var doppler_factor
Kennen Sie die Variable "doppler_factor"?
Sie dient dazu den bekannten Doppler-Effekt zu steuern. Je nach Wert (0-10) ist der Effekt weniger
oder mehr ausgeprägt.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│48
Versionskontrolle mit Subversion
mit Beispielen anhand einer 3D Gamestudio Demo-Applikation von Christian Behrenberg
Vorwort
Dieser Artikel sollte eigentlich kürzer werden als er tatsächlich wurde. Aber ich habe schnell
gesehen, dass eine Auflistung aller basics rund um Subversion und eine knappe Erklärung, was
man da macht, einfach nicht genug ist. Ich habe eine Einführung in die Revisionskontrolle
eingefügt und anhand eines trivialen Beispiels mit dem 3DGS das ganze versucht, anschaulich zu
machen. Literaturangaben und Quellen stehen am Ende des Artikels. Ich setze meine Hoffnungen
darin, das wenigstens ein paar Leute von diesem Artikel profitieren. Viele Menschen, die sich mal
kurz mit der Revisionskontrolle auseinandersetzen, sagen, dass es zuviel Aufwand sei. Vor allem
bei kleineren Projekten und wenn man alleine arbeiten würde. Ich sehe das nicht so, weil mir das
SVN eine Menge Sicherheit und Möglichkeiten bietet und mich durchdachter meine Projekte planen
lässt. In der professionellen Softwareentwicklung ist eine RC (= Revision Control) unabdingbar, weil
dadurch die Entwicklungszeit dramatisch verkürzt wird und dem Projekt eine nötige Stabilität und
Flexibilität verliehen wird. Viele kleine bis große Projekte, die unglaubliches Potential haben,
scheitern genau an diesem Punkt. Wissen und Erfahrung auf dem Gebiet des Projektmanagements
und den entsprechenden Tools dafür ist für die meisten ein gigantischer Schritt auf dem Weg vom
eher „dreckigen" oder „schluderigen" Weg der Projektführung (oder von Softwareentwicklung
allgemein) zu einem erfolgreicheren Weg - der zum gewünschten Ziel führt. Zwar gehört dazu eine
Menge eigener Einsatz (und vor allem der Wille!), aber wenn man weiß, was man machen kann,
dann ist einem auch schon geholfen - vorrausgesetzt, man wendet es auch an ;) RC ist ein
Standard in der Industrie und je früher man damit anfängt, desto besser ist das für sich selbst, für
das Team, aber am meisten für das Projekt. Deshalb hoffe ich, dass der Leser das Potenzial sieht
und nicht vor dem Artikel kapituliert - die investierte Zeit wird sich rentieren, ganz sicher.
Einführung
Typische Fehler in der Softwareentwicklung
Wer mit Spieleprojekten vertraut ist, bei denen sehr viel Quelltext und sehr viel Content produziert
wird, kennt so einige Situationen, in denen man fast verzweifelt, weil durch einen unglücklichen
Umstand das komplette Projekt auf der Kippe steht. Vor allem aber passieren solche Vorfälle auch
dann, wenn mehrere Leute an einem Projekt arbeiten. Hier nun einige Fälle, die Sie sicherlich
schon einmal durchlebt haben:
✗ Irgendwas im
am Ende bricht
dann mühsam
funktioniert das
code funktioniert nicht, man sucht den Fehler, man baut zahlreiche Fixes ein und
das ganze Programm ein. Nach etlichen Stunden oder Tagen Arbeitszeit hat man
durch teilweise lückenhafte Backups den code wiederhergestellt und vielleicht
Programm dann wieder - oder eben nicht. Das Projekt ist zum Scheitern verurteilt.
✗ Mehrere Programmierer haben an verschiedenen Spielmodulen gearbeitet und wollen nun alles
zusammenfügen - ein heilloses Chaos. Denn wie es aussieht, hat jeder Programmierer irgendwo
anders Modifikationen vorgenommen und man kann die neuen Sachen nicht einfach so
zusammenfügen. Es geht viel Zeit verloren, nur um die Sachen lauffähig ins Spiel zu integrieren sofern jemand dazu in der Lage ist, das überhaupt zu bewerkstelligen.
✗ Es arbeiten mehrere Leute an einem Projekt und alle sind über das Internet verstreut. Jeder will
die aktuelle Version haben, aber es gibt nur den Teamleiter, der immer den aktuellen Stand hat und
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│49
mal alle paar Wochen eine Version rausgibt, weil das immer so kompliziert ist mit dem
Zusammenpacken aller Daten. Ist er verhindert oder krank, kann das Projekt nicht fortgeführt
werden - alle müssen warten.
✗ Man kann nicht verfolgen, wer was wann gemacht hat. Wenn man dann beim Debuggen nach
Fehlern sucht und genau wissen muss, wann wo welche Änderungen weshalb von wem gemacht
worden sind - dann ist man meistens aufgeschmissen - weil es eben niemand weiß!
✗ Etc.pp. - typische Softwarefallen halt.
Solche Fälle passieren zu Hauf während einer Softwareentwicklung. In solchen Fällen leidet das
Team - und die Organisation bzw. die Projektverwaltung nimmt immer mehr Zeit in Anspruch als
notwendig. Mit einer sogenannten Versionskontrolle sind aber alle diese Probleme gelöst.
Was ist eine „Versionsverwaltung" und was hat das mit
Spieleentwicklung zutun?
Versionsverwaltung
Unter einer Versionsverwaltung versteht man ein System, welches typischerweise in der
Softwareentwicklung zur Versionierung und um den gemeinsamen Zugriff auf Quelltexte zu
kontrollieren, eingesetzt wird. Das System hält dabei immer die Änderung der Datei(en) fest, wer
sie bearbeitet hat und wann er das getan hat. Wogegen binäre Dateien (Bilder, Musik, etc.) immer
komplett gespeichert werden, werden bei Textdateien (code, Dokumentation, etc.) immer nur die
Unterschiede gespeichert, sodass man sich auch die Unterschiede anschauen kann - insbesondere
dann nützlich wenn man schauen will, was man selbst oder jemand anderes im code eigentlich so
verändert hat. Das ist sehr nützlich bei der Entwicklung von Programmen, Dokumentationen und
Veröffentlichungen, insbesondere auch dann, wenn mehrere Entwickler daran beteiligt sind.
Dabei wird sichergestellt, dass jeder Benutzer mit dem aktuellen Stand arbeitet oder auf Wunsch
auf die archivierten Stände zugreifen kann. Dadurch ist eine Versionsverwaltung nicht nur für
professionelle Entwickler in großen Teams, sondern auch für einzelne Entwickler interessant. Es
kann jederzeit eine ältere Version aufgerufen werden, falls eine Änderung nicht funktioniert und
man sich nicht mehr sicher ist, was nun alles geändert wurde - somit sind solche GAUs irrelevant,
weil man jederzeit auf die letzte funktionierende Fassung zurückgreifen kann. Dadurch, dass man
immer funktionierende Versionen in das System einfügt und anderen zugänglich macht, ist damit
schlussfolglich auch immer sichergestellt, dass jeder Benutzer Zugriff auf die aktuell voll funktionsund lauffähige Version der Software hat.
Anwendung bei Spieleprojekten
Spieleentwicklungen sind technisch gesehen die anspruchsvollsten Softwareproduktionen
überhaupt: man realisiert mehr oder weniger anspruchsvolle Softwarelösungen für die
verschiedensten Anforderungen, die es in der modernen Softwareentwicklung gibt. Dazu kommt,
dass heutezutage der Anteil des Grafik-contents immer beträchtlicher wird. Kein Wunder, dass an
kommerziellen Spielen Dutzende Leute arbeiten, zum Teil in verschiedene Teams unterteilt und in
diesen Teams Untergruppen mit verschiedenen Aufgabenbereichen. Auch kleine, unabhängige
Produktionen beschäftigen mittlerweile ein Gruppe von Entwicklern, die zusammen an einem Spiel
arbeiten. Solche Probleme, wie sie oben geschildert sind, wären wie ein halber Todesstoß für das
Projekt. Viele Amateur-Entwickler schließen sich nun auch über das Internet zusammen, um
gemeinsam an kleinen Spielen zu basteln.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│50
Die meisten Projekte scheitern allerdings, was statistisch gesehen durchaus plausibel ist: fehlende
Erfahrung, keine Geldmittel für Tools und eine undurchdachte, fast chaotische Organisation
kristalliert sich schon nach kurzer Zeit heraus. Man kann davon ausgehen, dass über 75% dieser
„Projekte" den Bach runtergehen. Das liegt aber auch daran, das meistens nur eine, maximal zwei
Personen Zugang zum source-code des Spiels haben. Das ist dann auch schon meistens der Haken,
weil diese Person selber entwickelt und meistens keine Ahnung davon hat, was sie eigentlich zutun
hat. Es entsteht kein echter Workflow, weil jeder nur über diese eine Person Zugang hat.
Ein Revision Control System, z.B. „Subversion", löst aber alle diese Probleme (s.o.). Nun können
alle Leute gleichzeitig an dem Spiel arbeiten, jederzeit eine aktuelle Version herunterladen, Zugriff
auf alle Änderungen haben, zu unterschiedlichen Zeiten daran arbeiten und live neue
Dateiversionen einspielen, wenn man zeitgleich zeitkritisch an einem bugfix arbeitet, etc. Grafiker
können dann auch ihre Dateien unter Revision Control setzen, Änderungen durchführen und wenn
Sie später feststellen, dass die aktuellen Änderung im Spiel schlecht aussehen, das ändern.
Komplizierte Backupsysteme sind somit nicht mehr nötig und die Entwicklung kann viel
dynamischer und viel sicherer stattfinden.
Subversion und andere Tools
Es gibt eine Reihe von Revision Control Software auf dem Markt, sowohl kommerzielle als auch
kostenlose. Subversion ist ein Open Source Projekt und der inoffizielle Nachfolger von CVS. Es gibt
auch einige Tools, wie z.B AlienBrain, die speziell auf content-reiche Projekte, wie eben
Spieleproduktionen, ausgelegt sind. Allerdings kosten diese auch z.T. viel Geld. Es gibt eine
Windows shell-extension für Subversion, „Tortoise SVN" genannt, welches in diesem Artikel
vorgestellt und benutzt wird. Im Folgenden wird Subversion mit SVN abgekürzt.
Download und Installation von Subversion auf einem Einzelplatz PC
✔ Besuchen Sie die Internetseite http://tortoisesvn.tigris.org/
✔ Klicken Sie auf den Bereich „Download" (http://tortoisesvn.net/downloads)
✔ Es werden 32-bit und 64-bit Versionen vom SVN angeboten. Klicken Sie auf die entsprechende
Installerfile. Sie werden automatisch auf die entsprechende Source Forge Seite re-directed, wo Sie
automatisch die Installationsdatei herunterladen.
✔ Wenn Sie die Datei herunterladen haben, starten Sie sie und folgen Sie den
Bildschirmanweisungen. Am Ende haben Sie das SVN und die Tortoise shell erfolgreich installiert.
Eventuell müssen Sie den PC neustarten.
Wie funktioniert das SVN?
Eine kleine Geschichte
Das SVN benutzt ein sogenanntes Repository. Diese Repository logged alle geänderten Dateien,
Modifikationen im SVN, wer was wann gemacht hat. Wenn Sie einen neuen Ordner erstellen und
dort die aktuellste Version der unter RC gestellten Dateien haben wollen, so ziehen Sie eine
sogenannte Working Copy („WC") - dies impliziert, dass jede WC lauffähig und funktionabel ist.
Stellen Sie sich nun vor, Sie sind Programmierer und wollen eine Änderung vornehmen, z.B. die
Gegner in Ihrem Spiel intelligenter machen. Sie ändern die Dateien in der WC und wollen diese
geänderten Dateien nun in das Repository hochladen (damit die anderen Entwickler des Spiels
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│51
auch Zugriff auf den geändert Code haben). Den Upload ins Repository nennt man „Commit". Das
heißt, dass Sie ihre Änderungen dem System mitteilen. Es wird nicht nur ihre User-ID gespeichert,
sondern auch wann sie commited haben und welche Dateien sie modifiziert haben (und wie). Sie
können optional auch noch eine change-log Message einbauen, die einen Kurzüberblick gibt.
Nehmen wir an, ihr Programmierkollege im Büro nebenan hat diesselbe Version der WC vm
Firmenserver gezogen und hat nun auch im Gegnerskript was an der Animation geändert. Sie
haben also die beiden gleichen Dateien bearbeitet, sie haben aber schon comitted. Was passiert
nun, wenn ihr Kollege comitten will? Das SVN bemerkt diesen Conflict und teilt diese ihrem
Kollegen mit. Er kann sich nun die Unterschiede von seiner zur neuen Version der Datei anschauen
und entscheiden, welche Codeteile von ihm übernommen werden, welche von Ihnen entfernt
werden oder welche Teile gemergedt (zusammengefügt) werden. Nach dem Commit von ihrem
Kollegen (er teilt es Ihnen über einen Messenger mit), sind sie neugierig auf die neuen
Animationen im Zusammespiel mit ihrer KI. Sie machen also ein Update und dabei werden die
Änderungen (Changes) direkt in ihrer WC geändert. Sie freuen sich: es sieht gut aus und die
Zusammenarbeit fand gleichzeitig ohne Probleme statt.
Anmerkungen zum Multi-User System
Im Folgenden wird Ihnen nun erklärt, wie sie selbst eine SVN RC auf ihrem Einzelplatz PC
einrichten und bedienen.
Wichtig: wenn Sie Subversion auf einem Server benutzen wollen, den Sie von überall aus
erreichen wollen, so brauchen Sie einen Root-Server Account bei Ihrem Hoster oder einen eigene
Server, weil Sie den Server entsprechend konfigurieren müssen. Daher wird in diesem Artikel nur
auf die Einzelplatzbenutzung eingegangen. Weitere Details zur Benutzung des SVNs als Server
finden Sie im OpenBook „Versioncontrol with Subversion" (http://svnbook.red-bean.com/).
Wenn Sie im Netzwerk arbeiten, so können Sie Subversion auf einem Rechner einrichten und das
Repository als Netzlaufwerk verbinden. Im Folgenden werden auch Situationen aus einem MultiUser Betrieb geschildert, allerdings trifft dies auch zu, wenn Sie alleine mit dem SVN arbeiten - es
dient nur der Veranschaulichung. Damit Sie gleich die Benutzung im Zusammenhang mit dem
3DGS lernen, wird dies an einem Miniprojekt erläutert.
Der normale Arbeitsablauf mit dem SVN - Features und Erklärungen
Subversion hat viele Features, Optionen und viele Kleinigkeiten und Extras - aber im täglichen
Betrieb werden Sie nur ein paar benutzen. Der typische Arbeitsablauf (oder -zyklus) mit dem SVN
sieht so aus:
• man updatet seine eigene Working Copy
• SVN update
• man macht seine Änderungen (neuer code, bugfixes, neue Grafiken, etc.)
• SVN add (neue Dateien hinzufügen)
• SVN delete (Dateien löschen)
• man schaut sich seine Änderungen an
• SVN status (Dateistatus (s.o.) abfragen
• SVN diff (Unterschiede zur letzten oder einer anderen Revision angucken)
• SVN revert (die geänderte Datei auf den letzten WC Stand bringen oder auf den Stand einer
anderen Revision)
• man merged seine Änderungen mit den Änderungen der anderen Entwickler
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│52
• SVN update (s.o.)
• SVN resolved (bei Konflikten)
• man commited seine Änderungen ins SVN Repository
• SVN commit
Das Repository
Bevor wir nun das Spieleprojekt überhaupt starten, erzeugen wir uns ein leeres Repository,
welches gleich die ersten Daten von der ersten unter RC gestellten Version unserer Demo enthalten
wird.
1. Erstellen Sie in Ihrem Projekte-Verzeichnis (wenn Sie denn eins haben) einen Ordner für unsere
SVN Demo. Ich habe ihn „SVNDemo" genannt. Erstellen Sie dort ein Verzeichnis, welches das SVN
Repository beherbergt. In meinem Beispiel lautet der Ordner „SVNDEMO_REPO".
2. Klicken Sie mit der rechten Maustaste auf diesen Ordner. Sie sehen 2 neue Icons im
Kontextmenü: „SVN Checkout" und „TortoiseSVN". Zeigen Sie auf „TortoiseSVN" und klicken Sie auf
„Create repository here...".
3. Im folgenden Dialog werden Sie gefragt, welches Dateisystem Sie wählen wollen. Da uns das
egal ist, bleiben wir beim „Native filesystem (FSFS)". Das Erstellen eines SVN Repository in diesem
Ordner wird dann bestätigt.
Glückwunsch! Ihr Repository ist nun eingerichtet. Bitte ändern Sie NICHTS in diesem Ordner, das
wird später das SVN für Sie übernehmen. Bevor wir die erste Spielversion comitten, müssen wir
erst eine erste Version überhaupt erstellen:
1. Erstellen Sie im Ordner „SVNDemo" einen temporären Ordner „temp"
2. Starten Sie den WED und erzeugen Sie einen hollow-cube und weisen Sie ihm die StandardTextur zu. Speichern Sie die Szene als room.wmp in diesem temp-Ordner und kompilieren Sie die
WMB Datei.
3. Erzeugen Sie eine .wdl Datei in diesem Ordner und nennen diese „main.wdl". Weisen Sie diese
WDL Datei dem Level zu. Schreiben Sie folgenden code in die WDL Datei:
function main ()
{
level_load("room.wmb");
wait(3);
while (1)
{
camera.pan += 5 * time_step;
wait(1);
}
}
Wenn Sie das Level über den WED starten, dreht sich die Kamera andauernd im Kreis.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│53
Die soll unsere erste Version des Spiels sein. Ihnen werden alle Features vom SVN anhand dieses
Beispiels erklärt. Nun wollen wir aber diese Version in das Repository als erste Version importieren:
1. Klicken Sie mit der rechten Maustaste auf den Ordner „temp".
2. Gehen Sie auf „TortoiseSVN \ Import...". Im folgenden Import-Fenster werden Sie zunächst dazu
aufgefordert die URL des Repositories anzugeben. Da es sich bei Ihnen auf der Festplatte befindet,
klicken Sie auf „..." und klicken Sich durch ihr System bis zu diesem Ordner. Markieren Sie ihn und
klicken
Sie
auf
OK.
Im
Textfeld
müsste
dann
z.B.
sowas
wie
„file:///I:/Projects/SVNDemo/SVNDEMO_REPO" stehen.
3. Bei jedem Import können Sie eine Import-Message anlegen. Geben Sie beispielhaft „SVN-Demo
Repository eröffnet!" an.
4. Klicken Sie OK. Sie sehen dann, wie das SVN die Dateien in das Repository addet.
5. Nun löschen Sie den Ordner „temp". Er wird nicht mehr benötigt.
6. Erzeugen Sie nun den Ordner, unter dem Sie das unter RC stehende Spiel finden. Nennen Sie
ihn z.B. „work".
7. Klicken Sie mit rechter Maustaste auf diesen Ordner und dann auf „SVN Checkout...". Sie
müssen unter „URL of repository" ihr Repository angeben - i.d.R. wird das eben erstellte angezeigt.
Klicken Sie auf HEAD Revision um den aktuellsten Status zu ziehen. Klicken Sie auf OK und sie
sehen, welche Daten das SVN aus dem Repository holt.
8. Der „work" Ordner hat jetzt ein kleines grünes Häkchen, genauso wie jede Datei. Ein grünes
Häkchen bedeutet immer, dass diese Datei seit dem letzten Abgleich mit dem Repository nicht
verändert wurde.
Glückwunsch! Sie haben gelernt, wie Sie ein Repository erstellen, eine erste Dateiversion unter
Revisionskontrolle stellen und in ein Repository importieren. Außerdem haben Sie gelernt, wie Sie
eine Working Copy beziehen.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│54
Dateien verändern und committen
Wollen wir unseren Sourcecode ein wenig verändern. Sie stellen fest, dass der Kameracode lieber
in eine eigene Kamerafunction gehört, die von der main function aufgerufen werden soll. Sie
schreiben nun stattdessen:
function cam();
function main ()
{
level_load("room.wmb");
wait(3);
while (1)
{
cam();
wait(1);
}
}
function cam ()
{
camera.pan += 5 * time_step;
}
Nachdem Sie auf „Speichern" geklickt haben, hat sich das Icon der Datei verändert:
Das rote Ausrufezeichen signalisiert, dass die Datei verändert ist. Nun wollen Sie die Datei
commiten, damit die Datei gesichert ist. Dazu klicken Sie mit der rechten Maustaste auf den „work"
Ordner und dann auf „SVN commit ...". Im folgenden Fenster sehen Sie ein Feld für die Changelog,
wo sie etwas eingeben können und ein Fenster, indem alle Änderungen angezeigt werden. Klicken
Sie auf OK. Nun ist die Änderung im SVN verzeichnet. Ändern Sie nun wieder was im Code:
schreiben Sie irgendwas rein, einen Kommentar zum Beispiel, und bauen Sie einen Fehler ein:
//meine kleine Kamerafunktion
function cam ()
{
camera.pan += 0 * time_step;
}
Die Datei ist wieder mit einem roten Ausrufezeichen versehen. Nun, das Programm läuft nicht.
Nehmen wir mal an, sie wissen nicht mehr was Sie verändert haben und wollen das jetzt wissen und nehmen wir mal an, sie wissen auch nicht mehr, welche Dateien Sie verändert haben. Klicken
Sie einmal mit der rechten Maustaste auf den „work"-Ordner und dann auf „TortoiseSVN\\Check for
modifications". Sie sehen dann einmal alle Änderungen auf einen Blick. Aha, Sie haben die Datei
„main.wdl" geändert. Klicken Sie mit der rechten Maustaste auf die Datei und dann auf „Compare
with base" - nun wird die Datei mit der letzten Version aus dem Repository verglichen. Dann sehen
Sie folgendes:
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│55
Sie sehen links die letzte Fassung aus dem letzten Update / WC und rechts die Änderungen. Zeilen
mit einem + Zeichen weisen auf eine Änderung oder einer neuen Zeile hin und - (Minus-) Zeichen
auf veränderte, bzw. gelöschte Zeilen. Sie sehen, das der Kommentar neu ist und das sie die
camera.pan - Zeile geändert haben. Sie sehen, dass da eine 0 steht. Die Kamera dreht also nicht das ist der Fehler! - Ändern Sie ihn aber committen Sie ihn (vorerst) nicht.
Neue Dateien, updates und merging
Bevor jetzt weitere Features besprechen, ziehen Sie eine weitere Working Copy in den Ordner
„work2". Dort müsste nun der fehlerhafte Code drin sein. In „work" haben Sie den ja schon
korrigiert, aber noch nicht commited. „Work" hat also ein rotes Ausrufzeichen, während „work2" ein
grünes Häkchen hat.
Fügen Sie nun ein Sprite in „work" ein und stellen Sie diesen in ihr Level und kompilieren Sie die
Levelfile erneut. Nun müssten ein paar level-Dateien ein rotes Ausrufezeichen haben. Der Sprite
hingegen hat kein Symbol - die Datei steht nicht unter Versionskontrolle. Um diesen Sprite zu
erfassen, klicken Sie mit einem Rechtsklick drauf und dann auf „TortoiseSVN\\add..". Die Datei hat
ein blaues + Zeichen und wird beim nächsten Commit dem Repository hinzugefügt. Committen Sie
diesen Stand des „work" Ordners.
Stellen Sie sich vor, die WC im Ornder „work2" wäre auf dem PC eines anderen Programmierers.
Der hat den Kamerafehler entdeckt und baut noch eine laufende Tilt-Veränderung ein:
function cam ()
{
camera.pan += 2 * time_step;
camera.tilt += 1 * time_step;
}
Er hat weder den Kommentar eingebaut, noch diesen Sprite. Er denkt sich, bevor er committed:
„vielleicht hat ja schon jemand weiter gearbeitet".. er macht also ein update, indem er mit rechter
Maustaste auf seine WC klickt und dann auf Update klickt. Er sieht, wie die Sprite-Datei geaddet
wird, die Levelfiles geupdated wird bei der Script-Datei - die er gerade bearbeitet hat, steht
„merged" - was heißt das? Er guckt in die Datei und stellt fest, dass dort z.B. der Kommentar neu
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│56
ist. Das SVN ist in der Lage, neue Änderungen von außen (durch ein Update) zu erkennen und die
geänderten Dateien anzupassen, sodass beide Versionen zusammengefügt werden. Der
Programmierer von „work2" startet sein Programm und sieht seine neue Kamerarotation und den
geupdateten Sprite. Er ist zufrieden und committet die neue Version.
Dateien verändern
Grundsätzlich gilt: alle Sachen, die man an einer Datei ändert, muss das SVN mitkriegen. Wenn Sie
innerhalb vorhandener Dateien was ändern - die unter RC stehen - dann ist das ok. Wenn Sie aber
- mit der Hand, also im Windows Explorer - Dateien löschen, umbenennen, verschieben o.ä., dann
meckert das SVN.
Dateien umbenennen
Wir haben jetzt eine Date „sprite.bmp" in unseren Ordner getan, der im Level angezeigt wird. Wir
wollen aber, das er anders heißt. Sie müssen jetzt über das SVN diese Datei umbenennen, sonst
zeigt das SVN an, dass die Datei „sprite.bmp" fehlt und die umbenannte Datei wird als nicht RC
stehend anerkannt - obwohl es ja prinzipiell die gleiche Datei ist. Klicken Sie mit der rechten
Maustaste auf die Datei und dann auf „TortoiseSVN\\Rename..". Geben Sie im Dialogfeld
„testSprite.bmp" ein. Durch ein blaues + Zeichen wird die Änderung signalisiert. Vergessen Sie
nicht in der WMP Datei den Sprite abzugleichen und neu zu kompilieren.
Dateien löschen
Sie stellen fest, dass es in dem Ordner Dateien gibt, die Sie für das editieren des Levels nicht
benötigen, weil sie sowieso immer automatisch erzeugt werden, wenn sie nicht vorhanden wären.
Dazu gehören „*.bak" Dateien, als auch die Dateien „*.$$M", „*.$$w", „*.raw" und „*.wed".
Markieren Sie alle diese Dateien und klicken Sie mit rechter Maustaste auf diese und dann auf
„TortoiseSVN\\Delete". Die Dateien werden sowohl physikalisch aus dem work Verzeichnis entfernt
als auch aus der Revisionskontrolle herausgenommen. Wenn Sie jetzt committen, wird das an das
SVN Repository weitergegeben. Wenn ein anderer user jetzt ein update machen würde, würde das
SVN bei ihm diese Dateien auch löschen.
Dateien ignorieren
Wenn Sie jetzt wieder an der WMP arbeiten, werden diese Dateien wieder erzeugt. Nun, es kommt
darauf an, was unter RC steht - Ihnen ist es aber egal, ob diese Dateien bei Ihnen in der WC
herumliegen. Sie können im SVN auch ignore-tags setzen, sodass das SVN diese Dateien „nicht
sieht".. also ignoriert. Editieren Sie also die WMP (machen Sie den hollow cube größer oder so),
speichern Sie die wmp ab und kompilieren Sie. Sie sehen dann, dass die neuen Dateien kein SVN
Symbol haben:
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│57
Logs
Bei jedem Commit können Sie eine Log-Message eingeben, die gespeichert wird. Das ist dann
besonders interessant, wenn Sie wissen wollen, was bei jeder Revision geändert wurde. Das
können Sie auf das gesamte unter RC stehende Projekt tun, aber auch nur für Ordner und auch für
einzelne oder mehrere Dateien. Klicken Sie z.B. mit der rechten Maustaste auf den Sprite und dann
auf „TortoiseSVN\\Show log". Sie sehen dann z.B. Folgendes:
Sie können einen Zeitraum der Log (für diese Datei in diesem Fall) angeben, von dem Sie
auswählen wollen. Dann steht in einem Fenster jede Revision, in der die Datei geändert wurde, wer
die Datei geändert hat, welche Actions auf die Datei ausgeübt wurde(n), wann dies getan wurde
und eine Kurzform der log message. Wenn Sie einen Eintrag auswählen, wird die Log dann
angezeigt.
Repository Browser
Man kann sich auch die aktuelle „Head" (= Kopf) Revisionstruktur im Repository anschauen, oder
eben eine spezielle. Dort wird dann die Verzeichnisstruktur des Repositories angezeigt und alle
dazugehörigen Daten wann was von wem wie verändert wurde. Hier nun ein Beispiel eines
größeren Repositories von mir:
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│58
Wann soll man immer commiten?
Im Prinzip könnte man sagen, das dies egal ist. Wenn man viele Änderungen oder ein großes
neues Feature oder sowas einbaut, so sollte man immer in kleinen Häppchen commiten - damit bei
evtl. Fehlern schnell wieder reverted werden kann. Wenn man eher immer große commits macht,
dann kann man beim späteren Rekonstruieren eventuell die Übersicht verlieren, weil zuviel auf
einmal gemacht worden ist.
Reverten
Das reverten ist eigentlich ganz einfach. Wir wollen nun einen einfaches Beispiel machen: nehmen
Sie den Testsprite, laden Sie ihn in ein Grafikprogramm und malen Sie was darauf, sodass er
verändert wird. Committen Sie die neue Version. Malen Sie nochmal was drüber, und committen
Sie nochmals. Die neue Revision hat nun eine Nummer, z.B. 10. Der Sprite in Revision 8 war also
der ursprüngliche Stand. Nehmen Sie einmal an, dass ist eine Textur oder so und Sie als Grafiker
haben neue Versionen hochgeladen.
Änderungen tätigen, nicht commiten, aber reverten
Nehmen Sie an, sie zeihen nun ein update und wollen den Sprite verändern (tun Sie dies!). Sie
stellen fest, dass die Änderung schlecht aussieht und wollen zum Stand der WC. Klicken Sie mit der
rechten Maustaste darauf und dann auf „TortoiseSVN\\Revert...". Sie sehen dann alle geänderten
Dateien (in diesem Fall der Sprite). Klicken Sie auf OK und die Datei ist auf dem alten Stand - sie
ist reverted worden.
Auf eine ältere Revision reverten und als neue Revision commiten
Wenn Sie nun feststellen, dass die allererste Version, z.B. aus Revision 8, viel besser aussieht als
alle nachfolgenden Revisionen (oder das ein code damals funktionierte und alle Neuerungen
danach nur schlechte bugfixes waren) und sie wollen diese jetzt wieder - so geht das auch! Stellen
Sie sicher, dass die Datei auf dem Stand der WC ist (bei einer Änderung also erst reverten). Gehen
Sie dann im SVN Menü auf „Update to Revision" und geben Sie die gewünschte Revision an.
Wichtig: die Datei ist dann nicht auf dem Stand der aktuellen Revision! Sie müssen dann den
Dateiinhalt kopieren, die Datei wieder auf die Head-Revision bringen (auch mit „Update to
revision") und die aktuelle Dateiversion mit dem Duplikat der „zurückgeholten" Datei
überschreiben. Wenn Sie jetzt commiten, ist dann der Inhalt der „alten" Revision wieder „neu".
Alte Dateien, die früher mal gelöscht wurden, wiederherstellen
Sie können wie oben gezeigt, im Repository-Browser alte Revisionen anschauen. Wenn Sie nun
eine alte Datei, die früher einmal gelöscht wurde, wiederherstellen wollen, dann suchen Sie sich
zunächst die letzte bekannte Revision der Datei heraus. Dann können Sie im Repo-Browser - wenn
sie diese Datei gefunden haben - die Datei irgendwo auf ihrem Computer speichern. Dann haben
Sie die Datei wiederhergestellt!
Ein Blick über den Tellerrand
Dies sind nur die Basisoperationen, die Sie kennen müssen. Es gibt viele Ausnahmesituationen,
denen Sie begegnen (z.B. conflicts, filelocks, etc.) werden, aber weitere Details dazu finden Sie im
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│59
oben genannten OpenBook. Wie Sie das SVN als server einrichten, steht dort auch - eine Erklärung
wie man das macht und das SVN für diesen Betrieb einstellt, würde den Rahmen dieses Artikel bei
weitem sprengen. Dazu gehört nämlich unter anderem der uneingeschränkte Zugang zu einem
Server. Ich bezweifle das der durchschnittliche Leser einen solchen Besitzt oder Geld für einen
Root-Server ausgibt. Wer aber die notwendigen Ressourcen hat, sollte sie aber auch anwenden:
erst durch serverbasierte RC kann man ein echtes Projekt durchziehen, bei denen die Mitglieder
einer Gruppe weit verstreut sind. Gerade bei internationalen Projekten mit Zeitzonen usw. ist das
überaus hilfreich.
Eine weitere Software, die ich in diesem Zusammenhang erwähnen will, ist das sogenannte TRAC,
welches man mit dem SVN nahtlos kombinieren kann. Es ist eine Art Projektmanagement
Software, die Aufgaben über Tickets verteilt, die bestimmten Personen zuteilen kann. Man kann
auch bugreports einreichen, in den Tickets Diskussionen führen (z.B. wenn es um neue Features
oder reporduzierbare bugs geht). Über sogenannten GANTT charts kann man Zeitpläne zur
Projektrealisierung durchführen und anzeigen - und vieles mehr!
Ich bedanke mich für Ihre Aufmerksamkeit,
mit spielerischen Grüßen,
Christian Behrenberg
Literaturangaben
Version Control with Subversion; open book. URL:
http://svnbook.red-bean.com/
Subversion Website; URL:
http://subversion.tigris.org/
TortoiseSVN Website; URL:
http://tortoisesvn.tigris.org/
Wikipedia Artikel
http://en.wikipedia.org/wiki/Revision_control
http://de.wikipedia.org/wiki/Versionsverwaltung
http://de.wikipedia.org/wiki/Subversion (Software)
http://en.wikipedia.org/wiki/Comparison_of_revision_control_software
Autorenwebsite:
http://www.christian-behrenberg.de
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│60
Wings3d Tutorial Teil1
Hallo mein Name ist Ronny Leonhard und vielleicht kennt mich der ein oder andere aus dem 3DGS
Forum. Ich möchte heute in meinem ersten Tutorial erklären wie man Wings3d so einrichtet das
man damit vernünftig arbeiten kann. Wie gesagt das ist mein erstes und ich werde in weiteren
erklären wie man damit modelliert und Texturen auf dem Modell auflegt, bis hin zum exportieren
und importieren im WED.
Kurz was zur Software selbst, Wings3d ist ein kostenfreies 3D Programm mit dem man 3d Modelle
erstellen kann und auch für alles verwenden kann (darf). Downloaden könnt Ihr die Software bei
www.wings3d.com.
Start!
Startet euer Wings3d, für denjenigen der mit 3ds Max und G-Max gearbeitet haben sollte, ist die
Bedienoberfläche was neues, denn in Wings3d gibt's keine gleichzeitigen Ansichten von „Top, Front,
Left, Perspektive" hier wird immer in einer Ansicht gearbeitet. Man kann die Ansichten aber
umstellen, aber später mehr dazu.
Jetzt seht Ihr ein Rastermuster und die Richtungsanzeigen „X, Y, Z", Ihr könnt das Rastermuster
und die Achsen rechts oben aus und einblenden. Was beim Arbeiten manchmal sehr hilfreich sein
kann.
Damit man besser versteht was ich erklären möchte, erstelle ich einen „Cube" ( rechte maustaste
-> Cube ). Der Cube ist erstellt und nun möchten wir auch gern die hinteren Seiten bearbeiten
oder zumindest sehen können, also müssen wir den Cube drehen. Das funktioniert in Wing3d mit
dem Scrollrad, einfach klicken und schon kann man den Cube drehen. Soweit so gut, nun ist aber
unser Modell etwas länger und ragt über die Bildschirmlänge hinaus, also muss man das Modell
etwas verschieben um den Rest sehen zu können. Das geht so ohne weiteres nicht, dazu muss
man die Standardeinstellungen verändern damit dies auch geht.
Preferences -> Camera und stell bei Camera Mode auf „ 3ds Max". -> „OK".
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│61
Jetzt können wir das Modell verschieben und das geht mit dem Scrollrad. Das Wenden und Drehen
funktioniert fast immer noch genauso nur das Ihr zum Drehen jetzt die Taste „Alt" dazu mit
benutzen müsst, also „Alt + Scrollrad" und schon könnt Ihr das Modell wieder drehen.
Wer es mag kann auch die Hintergrundfarbe ändern, ich habe es bei mir gemacht weil ich es
besser finde so zuarbeiten. Leider gibt's die Software nicht in deutsch aber wer polnisch oder
schwedisch kann kann die Sprache umstellen. Es gibt auch noch andere Sprachen...
So jetzt habt Ihr die optimalen Einstellungen um gute Ergebnisse zu produzieren. Im nächsten
Tutorial erkläre ich wie man ein einfaches Modell erstellt.
Viel Spaß beim modellieren! Ronny
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│62
Interview mit Ulf Ackermann, Gewinner des Conitec
Spring Contests 2007
3dgs Magazin
Dein Spiel hat den letzten Conitec Contest gewonnen. Es sprüht vor lustigen Ideen und Features.
Was hat Dich zum Prinzip Utz Wollewutz inspiriert?
Ulf Ackermann
Ich habe einige Marble Madness Clones gespielt zu der Zeit. Da gab es zum Beispiel eins mit einem
Hamster in einer Kugel. Allerdings fand ich das recht trist, da die Umgebung nur aus farbigen
Quadraten bestand. Ich bin ein grosser Fan von Sonic. Da dachte ich mir, ich probiere einfach mal,
das Marble Madness Spielprinzip mit Jump and Run Einlagen zu würzen!
3dgs Magazin
Woher nimmst Du all die lustigen Ideen?
Ulf Ackermann
Nunja, die kommen mit der Zeit... Ausserdem ist einiges natürlich bewährt aus anderen
Spielprinzipien, zum Beispiel die Powerups. Ich mag Schafe, das sind einfach lustige Tiere. Ich
kann auch den Ton eines Schafes fast naturgetreu nachahmen, willst Du mal hören? ;-)
3dgs Magazin
Vielen Dank für das Angebot. ;-)
Du hast die Newton Physik Engine sehr kreativ eingesetzt. Kannst Du uns einige Tipps in Bezug auf
die Verwendung von Newton mitteilen?
Ulf Ackermann
Anfangs, als ich noch eine überschauliche Anzahl an Physikobjekten hatte, machte Newton
keinerlei Probleme. Hat man hingegen zuviele Objekte, kann es unter ungünstigen Bedingungen
abstürzen. Man sollte auch keine zu komplexen Modelle als Newtonentities nutzen! Am besten
verstreut man die Objekte, so dass maximal 4-5 auf einmal miteinander kollidieren können. Das ist
gut für die Performance! Für Kollision mit anderen Objekten, welche keine Newtonentities sind, hat
es sich bewährt ein "normales" Gamestudioentity auf der selben Postion mitzuführen und die
Kollisionen bequem mit Events zu organisieren.
3dgs Magazin
Das Spiel wirkt sehr sauber konstruiert und alles passt zusammen. Hattest Du einen Plan oder hast
Du einfach losgelegt?
Ulf Ackermann
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│63
Um ehrlich zu sein habe ich einfach angefangen. Ich hab mit Newton ein wenig herumgespielt und
das machte mir einen Mordsspass. Ich wollte diese Sandkastenidee aufgreifen. Das man quasi viel
umwerfen kann, Kettenreaktionen in Gang setzt und so weiter. Anfangs war Utz noch ein Igel. Mit
der Zeit ist das Ganze gewachsen und das Resultat ist ein Schaf gefangen in einer Kugel was sich
durch 30+ Level rollen muss. Gibt es eigentlich schon den Begriff Jump & Roll?
3dgs Magazin
War dies Dein erstes Projekt?
Ulf Ackermann
Nicht wirklich. Ich habe schon eine Menge gemacht. Über manches bin ich im nachhinein nicht so
stolz. Zum Beispiel gab es mal "Killerhuhn 3D", das erste Moorhuhn in 3D. Wenn ich mir das heute
anschaue, ist es mir ein wenig peinlich. Zu meiner Verteidigung: Ich war damals erst 17 und es
war mein erstes Projekt. Ansonsten hatte ich neben allerlei Experimenten einen
Westernshooter/adventure angefangen. Screenshots davon gibt es noch in AUM 7.
(http://www.coniserver.net/coni_users/web_users/pirvu/aum/aum7/english/images/danrecent_scr
eenshots.jpg)
3dgs Magazin
Hast Du schon Pläne für die Zukunft?
Ulf Ackermann
Allerdings. Ich werde auf jeden Fall bei Gamestudio bleiben. Weil ich glaube, daß ich als quasi
Einzelkämpfer mit der Hilfe von ein paar guten Modellern nur als Casual-Game Entwickler eine
Chance habe. Grosse Projekte werden es nicht - ich habe allerdings einige spassige Ideen für
kleinere Spiele. Mehr möchte ich noch nicht verraten.
3dgs Magazin
Was gefällt Dir an Gamestudio besonders gut?
Ulf Ackermann
Es ist "einfach", und läuft auf sehr unterschiedlicher Hardware nahezu absturzfrei. Das ist wohl das
grösste Plus und sehr wichtig wenn man Spiele für eine breite Zielgruppe mit "älteren" Rechnern
entwickeln möchte. Die Community ist wohl auch eine der besten, die mir über den Weg gelaufen
ist bisher.
3dgs Magazin
Und was findest Du eher nicht so toll?
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│64
Ulf Ackermann
Der Multiplayerteil ist momentan noch sehr unkomfortabel. Es ist zwar grundsätzlich möglich ein
Mehrspielerspiel zu entwickeln, allerdings ist der Aufwand extrem hoch. Der 2D Part gefällt mir
auch noch nicht so (mein Menü hat ca. 5000+ Zeilen Code), ein Drag & Drop Gui Editor würde der
Engine gut tun. Ausserdem sollte der Renderer etwas schneller werden. Die Map/Modelleditoren
sind zwar okay, aber auch hier gibt es innovativere, nutzerfreundlichere Entwicklungen.
3dgs Magazin
Was würdest Du Anfängern raten?
Ulf Ackermann
Lest meinen Blog (http://www.ackbytes.de)! ;-)
Nein, quatsch. Ich rate ganz klassisch dazu, als erstes die Grundlagentutorials durchzuarbeiten.
Danach sollte man sich ein total einfaches Spielprinzip hernehmen (z.b. Pacman, Asteroids,
Snake...) und das probieren mit Gamestudio nachzubauen. Natürlich mit eigenen
Änderungen/Ergänzungen. Man sollte es zuendebringen! Also selbst wenn es nur ein Level hat, ein
komplettes Spiel daraus machen mit Installationsprogramm, Hilfedatei usw. Daraus lernt man
enorm. Spieleentwicklung ist nicht nur Spass und dabei lernt man auch unangenehme Aufgaben zu
erledigen.
Vielen Dank an Ulf, daß er sich die Zeit genommen hat unsere Fragen zu beantworten!
Das Interview wurde von Torsten Fock im Auftrag des 3dgs Magazins durchführt.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│65
Interview mit Sven Paroth, dem Zweitplatzierten im
Conitec Spring Contest 2007
3dgs Magazin
Du hast mit "Angelas World" ein sehr reizvolles Spiel entwickelt, dass unter anderem von seiner
Einfachheit und Deinem besonderen Style lebt. Welches Programm hast Du benutzt um die
stilvollen Grafiken zu erstellen?
Sven Paroth
Alle Grafiken wurden mit Adobe Photoshop CS erstellt, welches ich leider nur auf meiner Arbeit
nutzen kann. An ungeduldigen Tagen hab ich dann Zuhause mit dem kostenlosen Programm
"GIMP" gearbeitet.
3dgs Magazin
Arbeitest Du mit einem Grafiktablett?
Sven Paroth
Nein. Da meine Grafiken alle nur einfarbig sind und ich jede Art von runden Formen vermeiden
wollte, reicht da eine Maus aus. Ich finde es auch persönlich angenehmer mit dem "Pen-Tool" von
Photoshop (erstellen von Pfaden) mit der Maus zu arbeiten, als mit einem Grafiktablett, da das
Nachbearbeiten der Pfade präziser mit einer Maus ist (meiner Meinung nach).
3dgs Magazin
Wie inspirierst Du Dich?
Sven Paroth
Wenn ich das wüsste... Ich kann das nicht erzwingen und mir sagen "so, jetzt denk dir mal was
neues aus". Das muss einfach von selbst kommen. Inspirieren tun mich sicherlich so einige Sachen
wie Menschen, Kunststile, Musik, etc...
3dgs Magazin
Der Lohn dafür war der zweite Platz im letzten GS-Contest. Hast Du damit gerechnet?
Sven Paroth
Mit dem zweiten Platz hab ich auf keinen Fall gerechnet. Ich war mir zwar mittlerweile bewusst,
dass das Spiel bei einigen Leuten gut ankam, aber als ich die Liste der teilnehmenden Projekte
gesehen habe, hab ich nicht geglaubt unter die besten 5 zu kommen. Projekte wie Utz Wollewutz,
Memowar oder ähnliches sind einfach umfangreicher als mein Projekt. Mir war´s besonders wichtig
3D 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
dankbar für den 2. Platz.
3dgs Magazin
Du hast im Forum schon des öfteren davon geschrieben, dass Du manchmal ein kleines
Motivationstief hast. Das geht uns allen so. Wie gehst Du damit um und wodurch steigerst Du
Deine Motivation?
Sven Paroth
Ohja das Motivationstief... Ich denke das ist das Hauptproblem Nr. 1 bei mir und vielen anderen,
was das scheitern an Projekten betrifft. Da sich meine Stimmung sehr häufig ändert und leicht von
vielen Dingen beeinflusst wird, gabs bei mir wirklich Wochen bis gar Monaten wo ich absolut keine
Motivation für irgendwelche Projekte hatte. Um das bei "Angelas World" zu ändern, hab ich
eigentlich recht wenig getan. Neue Motivation hab ich aber aus den ganz vielen positiven
Kommentaren zu meinem Projekt gewonnen. Sowas baut schon sehr auf. Im neuen Projekt,
"Angelas World 2", hab ich allein die Motivation vom Vorgängertitel mit eingebracht. Zur Zeit läuft
alles super und meine Motivation bleibt dauerhaft oben, was vor allem daran liegt, dass ich viel
mehr plane als vorher, mir Milestones setze, und die richtige Musik beim arbeiten auswähle.
3dgs Magazin
Standen alle Features des Spiels von vornherein fest oder hast Du "ins Blaue hinein" entwickelt?
Sven Paroth
Um ehrlich zu sein, nein. Das ganze Projekt basierte nur auf den Grundgedanken "Ich will ein Spiel
FERTIGSTELLEN". Die Grundidee für das Spiel hat mir meine Freundin verschafft. Bei der Grafik
habe ich vorher immer auf die "Masse" geschaut, was denen eventuell gefallen kann. Dadurch hab
ich oft Probleme beim Umsetzen bekommen. Aus dem Grund wollte ich diesesmal einfach meinen
persönlichen Stil nutzen und hatte bedenken das er bei niemanden gefallen finden würde. Mehr
Planung gabs eigentlich nicht. Der Rest kam durch meine Laune und wurde einfach "ins Blaue
hinein" entwickelt, um´s mal mit deinen Worten zu sagen.
3dgs Magazin
Was gefällt Dir an Gamestudio besonders gut?
Sven Paroth
Besonders gefällt mir einfach die Möglichkeit, mit einfachen Mitteln in kurzer Zeit wirklich
"brauchbare" Ergebnisse zu erzielen. Am Anfang kann man sich als Beginner mit Templates,
fertigen Modellen und Scripten bereits kleinere Spiele zusammenbauen. Wenn man dann
konkretere Projekte angehen möchte (egal welches Genre), schreibt man sich eben alles selbst,
gerade mit der A7 Engine und Lite-C. Zudem gibt es eine super Community, die bei Fragen oft gute
Antworten liefern, und durch Plugins das 3DGS immer weiter ausbauen.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│67
3dgs Magazin
Und was findest Du eher nicht so toll?
Sven Paroth
Schlecht finde ich eigentlich nichts an 3DGameStudio. Leute, die dauernd die A6 Engine mit der
Unreal 3 Engine oder ähnlichem vergleichen, haben einfach den Sinn für die Realität verloren. Es
hat schon seine Gründe wieso Engines wie die Unreal 3 Engine mehrere tausende Dollar kosten. Es
war auch mit Sicherheit nie das Ziel von Conitec, eine ähnliche Engine zu entwickeln. Meiner
Meinung nach gibt es keine bessere Engine für Neulinge und Fortgeschrittene in der Games
Industry als die A6 Engine. Man bekommt extrem viel für sein Geld und muss nur lernen wie man
selbst an seine Ziele kommt. Die Engine allein macht das Spiel nicht qualitativ. Wer dann
irgendwann mal reich ist und eine große Firma gründet, kann dann gerne zu den Königen der
Engines greifen
3dgs Magazin
Was würdest Du Anfängern raten?
Sven Paroth
Ich rate Leuten sich erstmal die Grundlagen mit der A6 Engine beizubringen. Dabei hilft es, das
Manual, Tutorials oder einfach Scripte von existierenden Projekten anzuschauen. Dann kann man
irgendwann anfangen, mit den Templates oder eigenen Scripten, kleine Spiele zu programmieren.
Geht auf Freewareseiten, schaut euch kleine Spiele an und versucht das ganze mit der A6 Engine
umzusetzen. Besonders wichtig ist hier bei die Planung! Um so früher man damit anfängt, desto
schneller wird man für spätere, größere Projekte Design Dokus und Konzepte schreiben können.
Ich hab ebenfalls viel zu oft gesagt das ich sowas nicht brauche, wie z.B. bei Angelas World. Das
war der Hauptgrund für meine Motivationstiefs. Im zweiten Teil ist alles schriftlich festgehalten und
man sieht direkt was realisierbar ist, was zu tun ist, wie Umfangreich das Projekt ist und kann so
viel gezielter und Motivierter arbeiten! Und bitte, fangt garnicht erst mit MMORPG's oder des
gleichen an. Sowas erfordert Jahre lange Erfahrung und ein professionelles Team.
Im Namen des 3dgs Magazins bedanke ich mich ganz herzlich bei Sven "Kihaku" Paroth für die
Beantwortung der Fragen.
Das Interview wurde von Torsten Fock im Auftrag des 3dgs Magazins durchführt.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│68
Interview mit Johann Christian Lotter, dem "Vater"
des 3D Gamestudios
JCL gibt Antworten
3dgs Magazin
Mit Lite-C schließen Sie eine Produktlücke und machen zugleich Gamestudio wesentlich flexibler.
Wie kamen Sie auf diesen kleinen Geniestreich? Was hat Sie inspiriert?
JCL
Lite-C ist kein Geniestreich, sondern nur die logische Fortentwicklung einer reinen Skriptsprache zu
einer Programmiersprache. C-Skript erlaubte nur Zugriff auf die Engine-Funktionen, lite-C dagegen
Zugriff auf alle Softwarebibliotheken des PC, insbesondere die DirectX-Funktionen. Dies ist ein
konsequenter Schritt für Gamestudio von einem reinen Spieleentwicklungssystem hin zu einem
universellen Entwicklungssystem für alle möglichen Programme.
3dgs Magazin
Vielen Usern mißfällt etwas die die Art, in der neue Features angekündigt werden. Einige hätten
gerne einen "Fahrplan", nach dem sie die Entwicklung größerer Projekte hinreichend planen
können. Auch wenn Sie verständlicherweise keine genauen Angaben machen können - wäre nicht
eventuell eine grobe "Timetable" denkbar?
JCL
Diesen Wunsch kann ich verstehen. Wir haben im Büro ein grosses Whiteboard, auf dem Features
mit Hilfe von Klebezetteln auf Termine verteilt sind. Diese Klebezettel lassen sich leicht abnehmen
und neu gruppieren, und das passiert auch ab und zu. Eine feste Timetable hingegen hat die
Eigenschaft, sich zu verselbständigen und das Kommando zu übernehmen. Entweder müsste ich
mich strikt daran halten (schlecht für mich) oder sie immer wieder abändern (schlecht für User, die
sich darauf verlassen). Deshalb lasse ich das lieber bleiben. Wir werden aber den Forecast
umgestalten, so dass User besser erkennen können, in welchem Entwicklungsstand sich die
verschiedenen Features befinden.
3dgs Magazin
Was hat Sie dazu bewogen Lite-C und MED als Freeware anzubieten? (anm.: nicht für kommerzielle
Zwecke)
3dgs Magazin
Ich kann es mir natürlich nicht verkneifen und es muß ja auch sein... Können Sie uns irgend etwas
über die Verbindung zu Atari mitteilen? Wir wollen uns doch nur für Sie freuen.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│69
JCL
Es freut mich, wenn ich mit einer Antwort gleich zwei Fragen erledigen kann: Atari haben Sie es zu
verdanken, dass lite-C und MED Freeware sind. Leider kann ich erst in ein paar Wochen mehr dazu
sagen.
3dgs Magazin
Sie haben eine besondere Art von Humor, die oftmals auf Logik begründet ist. Eigentlich schon ein
Markenzeichen. Waren Sie - mit Verlaub - schon immer so?
JCL
Wer mich kennt, weiss, dass ich nicht besonders witzig bin. Der Spassvogel in unserem Team ist
Doug.
3dgs Magazin
Gibt es für Sie ein "Lieblingfeature" an der Acknex Engine?
JCL
Ja, ein eher unauffälliges Feature: das Template-System mit dem sich selbst editierenden
Sourcecode per Kommentarmarken.
3dgs Magazin
Wo sehen Sie Gamestudio in fünf Jahren? Haben Sie eine Vision?
JCL
Mit dieser Frage werden oft Kandidaten in Bewerbungsgesprächen genervt: Wo sehen Sie sich in
fünf Jahren? Für Gamestudio hängt es davon ab, wie sich die PC-Hardware weiterentwickelt. In fünf
Jahren haben wir die A8 Engine, die keinen Map-Compiler mehr benötigt und nicht nur das
Rendern, sondern vermutlich auch Physik, Kollisionserkennung und Pathfinding per Hardware
erledigt. Und wir haben ein Template-System, das automatisch viele Grundtypen von Spielen und
Simulationen mit "Wizard"-Funktionen erzeugt.
3dgs Magazin
Warum Hilbert´s Hotel? Warum die Unendlichkeit? Können Sie uns etwas über Ihre zweite Passion
erzählen?
JCL
Warum die Unendlichkeit? Ich kann mir schlecht vorstellen, dass es jemanden gibt, den die
Unendlichkeit gar nicht interessiert. Wer aber mehr wissen will, kann sich den Einleitungs-Sermon
auf www.unendliches.net durchlesen.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│70
3dgs Magazin
Mal anders gefragt: Gibt es einen Rat, den Sie ambitionierten und erfahrenen Entwicklern mit auf
den Weg geben möchten?
JCL
Ambitionierte und erfahrene Entwickler brauchen keinen Rat von mir. Für weniger erfahrene
Entwickler hätte ich den Rat, ihre Ambitionen solange zu zügeln, bis ihre Erfahrungen aufgeholt
haben.
Mit freundlichem Gruss jcl / Conitec
Vielen Dank Herr Lotter, daß Sie sich die Zeit genommen haben auf unsere Fragen zu antworten.
Das Interview wurde von Torsten Fock im Auftrag des 3dgs-Magazins durchgeführt.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│71
SEED_IT for 3DGS
SEED_IT ist das hilfreiche Werkzeug für 3DGS, welches die Verteilung und Platzierung von Objekten
(Modelle/Sprites/Entities) bei der Levelgestaltung einfach und komfortabel macht.
Mit nur wenigen Mausklicks ist es möglich einen gesamten Level, eine Landschaft und vieles andere
zu erstellen und zu verändern. Mit SEED_IT hat das langwierige Platzieren einzelner Objekte ein
Ende.
Aber SEED_IT kann noch mehr...
Mit den zahlreichen Optionen kann die Sichtbarkeit, zusätzliche (benutzerdefinierte)
Aktionen/Funktionen, die Positionierung, die Größe, das Aussehen, das Material, Bewegung und
Animation, ..., der einzelnen Objekttypen schnell eingestellt und jederzeit verändert werden.
SEED_IT generiert aus den Einstellungen performantes c-script welcher für spezielle Wünsche
auch einfach erweiterbar ist.
Wie funktioniert SEED_IT?
SEED_IT verwendet je Objektplatzierung eine sogenannte SEEDMAP. Diese SEEDMAP ist ein
einfaches Abbild der Objektverteilung anhand der drei Grundfarben:
Jede der drei Grundfarben (R/G/B) repräsentiert dabei einen Objekttyp welcher wiederum aus bis
zu zehn verschiedenen Modelle, Sprites, Entities bestehen kann.
Der Farbwert (0..255) der einzelnen Grundfarben kann dabei auch noch die Dichte der
Objektverteilung bestimmen.
Die Verteilung der Objekte, welche sehr schnell in Echtzeit im Spiel durchgeführt wird, ist somit
eine Projektion der Objekte nach der SEEDMAP auf das Terrain oder Modell (SEEDGROUND).
Ein SEEDGROUND muss nicht zwingend sichtbar sein (z.B. bei Asteroiden).
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│72
Das Erstellen eines Levels in drei Schritten
Zum Erstellen eines Levels mit SEED_IT sind nur drei Schritte notwendig:
1. Vorbereiten des Levels, auswählen der Modelle und erstellen der SEEDMAP.
2. Definieren der Objekttypen und deren Eigenschaften mit SEED_IT sowie das generieren des
Scriptes mit einem Mausklick.
3. Einmalig das Einbinden des erzeugten Scriptes in das Projekt und auswählen der Seed-Action für
das Terrain.
Nachträgliche Änderungen am Leveldesign durch Neuplatzierung, Umsortierung, ändern der
Modelle oder deren Eigenschaften ist dann nur noch eine Sache von Sekunden.
Die Einstellungen in SEED_IT mit wenigen Mausklicks verändern, das Script neu generieren, und
im Nu ist das Aussehen des Levels verändert.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│73
SEED_IT bietet aber noch viel mehr!
- Aus-/einblenden der Objekte mit weichen Übergängen mit frei definierbarem Abstand
- automatisches entfernen/erzeugen der Objekte zur Reduzierung des Speicherverbrauchs
- Objektanimation oder -bewegung (Wind, Rotation, ...)
- Einstellen der physikalischen Eigenschaften der Objekte (3DGS pro erforderlich)
- Wettersimulation mit nur einem Schalter - einfache LOD-System Konfiguration
- einfaches Einstellen des fog-Systems
- Objektskills und -flags vordefinieren, Skins (fix/random Skin), Material (Material-LOD (einstufig))
- pixelgenaue Platzierung von einzelnen Modelle bis zur freien Verstreuung von vielen Modellen
- und, und, und...
Laden Sie sich die Demo herunter unter http://www.gameus.de und lassen Sie von nun an
SEED_IT for 3DGS die Arbeit der Objektplatzierung übernehmen.
SEED_IT for 3DGS Version 1.0 kostet nur € 25,- /~$33.Also nichts im Vergleich zu der Zeit für mühevolle manuelle Levelgestaltung.
Vielen Dank an Ulrich "mercuryus" Seiffert für die Erklärung des Tools und die Bereitstellung einer
Version für´s Autorengewinnspiel.
3D GAMESTUDIO-Magazin ■ Ausgabe 05 | Juni 2007
│74