Geschrieben von triplex am 09.12.2004, 18:08

UM DIESES TUTORIAL MIT ALLEN DESIGN ELEMENTEN + CSS DATEIEN SEHEN ZU KÖNNEN, BENUTZT BITTE DEN DIREKT LINK ( http://www.hawkgames.de/Tutorial.php )

C- Script von Anfang an Lernen
Ein Tutorial von Timo Stark in Zusammenarbeit mit Robert Andreas Ternes

Autor: Timo Stark (aka Triple-X, Hawkgames)
In Zusammenarbeit mit: Robert Andreas Ternes (Design ©2004 Pharao-Software)
Datum: 01.05.2004
Letzte Aktualisierung: 21.05.2004
Download: cscript_tut.zip

Inhaltsverzeichnis
Tipp: Durch Klicken auf einen Kapitelunterpunkt gelangen Sie sofort zur gewünschten Stelle. Über die Pfeilbuttons gelangen Sie wieder an den Anfang dieses Tutorials.

1. Einführung
Kapitel 1 Der Anfang
2. Kommentare

3. Variablen

4. Grundrechenarten mit Variablen

5. Die Main Function

5.1 Function Prototyping

Kapitel 2 Es geht los
6. Modulo

7. Arrays

7.1 Vektoren

7.1.1 vec_set(vektor1,vektor2);

7.1.2 vec_add(vektor1,vektor2);

7.1.3 vec_sub(vektor1,vektor2);

7.1.4 vec_dist(vektor1,vektor2);

8. Lokale Variablen

9. If / Else Unterscheidungen

10. Schleifen

11.1 Wait und Sleep Befehle

11. Starter

12. Actions

13. Parameter in Funktionen

14. Dateiarten und Definieren von Dateien

15. Panels

15.1 Aufbau eines Panels

15.2 Variablen darstellen (digits)

15.3 Buttons

15.4 Slider

15.5 Sonstige Paneleinstellungen

15.6 Layer (wörtlich übersetzt: Ebene)

16. Texte

16.1 Strings

16.2 Definierung eines Textes

17. Handbuch

18. Pointer (Zeiger)

19. Skills und Flags

20. Define

21. Einfache Maussteuerung

22. Reaktion auf Tastendrücke

23. Events

23.1 Event_Block

23.2 Event_Entity

23.3 Event_Impact

24. Splitten in mehrere WDL Dateien

25. Debugging

Kapitel 3 Nützliche Informationen
26. Tricks und Hinweise

26.1 If Trick

26.2 While Trick

26.3 Hinweis bei Parametern bei Buttons

26.4 Layer

26.5 Übersichtlichkeit

26.6 Klammern bei Events

26.7 Anzeigen von Skillnamen in WED

27. Grundlegende Funktionen

27.1 String Befehle

27.1.1 str_cpy(string1,string2);

27.1.2 str_trunc(string1,zahl);

27.1.3 str_clip(string1,zahl);

27.1.4 str_cmp(string1,string2);

27.2 Entity Eigenschaften

27.2.1 Pan Tilt Roll

27.2.2 Passable

27.2.3 Visible

27.2.4 Transparenz

27.2.4.1 Alpha

27.3 Sonstige Befehle

27.3.1 Trace

27.3.2 Snd_Play

27.3.3 Temp und Result

28. Wichtige Befehle

29. Abschluss

1. Einführung
Hallo

Sie haben schon hunderte von Tutorials durchgelesen und trotzdem schaffen Sie es einfach nicht eigenen Scripte zu schreiben?
Sie können eigentlich noch gar kein C-Skript und wollen es von Grund auf erlernen?
In beiden Fällen sind Sie mit diesen Tutorial hier richtig.
Ich hoffe, dass Ihnen dieses Tutorial hilft und Sie nach dem lesen in der Lage sind mit dem Handbuch umzugehen und Ihre eigenen Scripte zu schreiben.
Als aller erstes sollten Sie sich einen guten Scripteditor besorgen. Für Nutzer der A6 empfehle ich SED (im 3D Gamestudio Ordner).
Für Benutzer von A5 gibt es sehr viele verschiedene Script Editoren, wie GST Builder oder Wdledit. Am besten einmal auf der Downloadseite von 3D Gamestudio (http://www.3dgamestudio.de) suchen.

Viel Spaß beim lesen, TripleX

Der Anfang

2. Kommentare
In diesem Tutorial wollen wir mit Kommentaren anfangen. Kommentare kommentieren, wie der Name schon sagt, ihr Script. Wenn Sie ihre ersten schwierigeren Scripte schreiben werden Sie irgendwann feststellen, dass Sie ihre eigenen Scripte nicht mehr kapieren, wenn Sie sie nicht ausreichend kommentieren.
Kommentare haben keinerlei Auswirkung auf ihr Script. Sie sind ausschließlich dazu da, dass Sie und andere Leute in ihrem Team ihr Script verstehen.

Es gibt 2 Arten von Kommentaren:

//Alles was hinter diesen zwei Backslashs steht wird ignoriert

/* Alles was nach diesen beiden Zeichen steht wird von der Engine ignoriert.
Mehrzeiler sind möglich. Der Kommentar wird per folgenden Zeichen beendet: */

An dieser Stelle empfehle ich, Kommentare wirklich in schwierigeren Scripten zu benutzen.

3. Variablen
Variablen sind ein sehr wichtiges Thema in der Spieleentwicklung und in fast jeder anderen Scriptsprache. Variablen sind Platzhalter für Zahlen. Das heißt, dass Sie nichts weiter machen als Zahlen zu ersetzen.
Das hat folgende Vorteile:

Eine Variable kann fast jeden Namen haben den SIE wollen. Dies ergibt eine wesentlich bessere Lesbarkeit und Verständlichkeit des Scriptes.

Nehmen wir an Sie haben ein Waffensystem mit 20 Waffen, bei dem jede Waffe bei jedem Schuss um 1 Grad erhitzt. Nun stellen Sie sich vor Sie wollen 1 Grad durch 1.5 Grad ersetzen. Jetzt müssen Sie, wenn Sie Zahlen statt Variablen genommen haben 20 Zahlen von 1 auf 1.5 verändern. Wenn Sie eine Variable nehmen ändern Sie einfach den Wert bei der Variabelendefinition.

Variablen definiert man folgendermaßen:

var name = wert;

Eine Variabelendefinition beginnt immer mit den Stichwort „var“. Danach kommt der Name für die Variable. Über diesen Namen kann man die Variablen verändern und benutzen. „Name“ kann irgendein Name deiner Wahl sein. Als letztes wird der Variable noch über den Zuweisungsoperator = den Wert deiner Wahl zugewiesen.
Sie können übrigens eine Variable auch ohne Zuweisung definieren. In diesem Fall hat die Variable den Wert 0.

var name;

Ganz am Ende kommt noch ein Semikolon. Semikolons müssen an das Ende jeder Anweisung gesetzt werden, damit die Engine weiß, dass der Befehl zu Ende ist.
Wenn man einen Semikolon vergisst kommt es häufig zu Folgefehlern, was zur Folge hat, dass die Engine Ihnen 1000 von Fehlern ausspuckt obwohl Sie nur 1 Fehler gemacht haben.

4. Grundrechenarten mit Variablen
Nachdem wir im letzten Kapitel gelernt haben Variablen zu initialisieren, müssen wir jetzt auch noch lernen wie man mit ihnen rechnet. In C-Script kann man unter anderem die 4 Grundrechenarten Operatoren + (plus), - (minus), / (geteilt), * (mal), als mathematische Funktionen benutzen. Hier ein paar einfache Code Beispiele:

Var a = 5;
Var b = 2; //Definition von zwei Variablen

Function main() /*Was dies hier bedeutet lernen Sie im nächsten Kapitel. Schauen Sie sich bis dahin nur die Variabelenveränderungen an. */
{
a = a+b; //a ist jetzt 7
b = a*b; //n ist jetzt 14 (7 mal 2)
b = 2; //b wird jetzt einfach über = der Wert 2 gegeben
b += b; /*diese Zeile bedeutet das gleiche wie b = b + b;*/
a -= b; //a = 7-4 = 3
}

Die Kommentare sollten das meiste erklären. Wichtig ist noch, dass diese Zeilen...

a+=b;
a-=b;
a/=b;
a*=b;

...vollkommen das gleiche bedeutet wie folgende Zeilen:

a = a + b;
a = a - b;
a = a / b;
a = a * b;

Solche Abkürzungen sieht man in Programmiersprachen häufig (Programmierer sind ziemlich faul).

5. Die Main Function
Im oberen Kapitel haben Sie sie ja schon eine "Main Function" gesehen. Als erstes stellen wir uns die Frage: Was ist überhaupt eine Funktion?
Eine Funktion ist eine Reihe von Anweisungen die nacheinander ausgeführt werden. Eine Funktion wird folgendermaßen definiert:

Function Name()
{
//hier kommen alle Anweisungen hin
}

Alle Anweisungen von der Funktion stehen zwischen den beiden Klammern ( { und } ). Diese Klammern macht man mit der Tastenkombination ALT GR+ 7 bzw. ALT GR + 0.

Nun ist die Function Main aber eine besondere Funktion. Dies ist die Funktion die als erstes ausgeführt wird. Das ist der Grund, warum in der Function Main häufig z.B. das Level geladen wird.

Funktionen werden nicht automatisch ausgeführt, sondern müssen erst aufgerufen werden. Sie tun dies mit "Funktionsname();". Die main Funktion bildet hierbei eine Ausnahme. Diese Funktion wird beim Start der Engine aufgerufen. Nun ein Beispiel wie Sie eine Funktion aufrufen können.

Var function_test;

Function my_function()
{
function_test=2;
}

function main()
{
my_function(); //Funktion wird aufgerufen
}

In diesem Fall wird beim starten der main Funktion die Funktion my_function() aufgerufen. Durch diesen Aufruf springt die Engine zu dieser Funktion und führt alle Anweisung in ihr aus. Danach fährt sie mit der alten Funktion fort.
Sie müssen my_function VOR der main Funktion schreiben, damit der Compiler die Funktion bereits kennt wenn sie aufgerufen wird.
Nur was ist, wenn Sie nicht alles über eine Funktion schreiben wollen, oder sich zwei verschiedene Funktionen gegenseitig aufrufen?
Das kommt in den nächsten Kapiteln!

5.1 Function Prototyping
Um eine Funktion in z.B. der Main Funktion nutzen zu können, wenn Sie die Funktion erst unter der Main Funktion schreiben müssen Sie nur am Beginn ihres Programms die Funktionsdefinition schreiben. Das Funktioniert folgendermaßen:

Function my_function; //Definierung der Funktion

Function main()
{
my_function();
}

function my_function()
{
//Anweisungen
}

Nun kennt der Compiler die Funktion my_function schon bevor er Sie aufruft. Deshalb gibt es keine Probleme.

Es geht los

6. Modulo
Ja ich weiß auch, dass Sie jetzt wahrscheinlich dieses Thema überspringen wollen. Was will man schon mit der mathematischen Funktion Modulo!? Trotzdem will ich Modulo kurz hier zur Vollständigkeit erklären.

Modulo ist der Rest einer Division. Hört sich als erstes kompliziert an ist aber ganz einfach. Das Zeichen für die mathematische Funktion Modulo ist % (wird genauso angewendet wie plus, minus usw.).

Ein paar Beispiele zum Verständnis:

Var a; //Bei einer solchen Definierung von Variablen bekommen die
Var b; //Variablen den Wert 0.

Function main()
{
a=12;
b=5;

a%=b; //a ist nun 2. Da: 12 / 5 = 2 REST 2
}

Dieses Codebeispiel sollte alles erklären.

7. Arrays
Bei einem Array handelt es sich um einen Verbund von mehreren Variablen.
Eine Erklärung an einen konkreten Beispiel:
Sie möchten ein Waffensystem mit 10 unterschiedlichen Waffen schreiben, die alle einen unterschiedlichen Schaden haben. Hier gibt es nun 2 Möglichkeiten. Entweder schreiben Sie 10 verschiedene Variablen(
Var schaden_waffe1;
Var schaden_waffe2;
//usw.
)
oder Sie benutzen einen Array, den Sie wie folgt definieren:

var name[n];

Name ist wie immer ein Name den Sie sich selber auswählen können. Nun kommt eine rechteckige Klammer mit einer ZAHL drinnen (n soll irgendeine Zahl repräsentatieren). Diese Zahl gibt die Anzahl an Variablen an, die in den Verbund sind. Sie können den einzelnen Variablen in den Array natürlich auch bei der Definierung einen Wert geben. Das funktioniert folgendermaßen:

Var erster_array[4] = 20,24,17,20;

Jetzt hat die erste Variable in erster_array den Wert 20, die zweite den Wert 24, die dritte den Wert 17 und die vierte den Wert 20.
Man kann jetzt folgendermaßen auf die Arraywerte zugreifen:

Erster_array[0]=10;

Dies verändert den ersten Wert des Arrays auf 10. ACHTUNG: Der erste Wert wird mit [0] aufgerufen, der zweite mit [1] usw. der letzte mit [n(in der Definition geschrieben) – 1]. Wenn Sie die Arraygrenzen überschreiten wird ihnen die Engine sofort einen Fehler ausspucken. Ein typischer Fehler:

Var new_array[3];

Function main()
{
new_array[10]=2; /*Erzeugt einen Fehler weil new_array nur 3 Variablen hat!*/
}

Nun wollen wir mal einen Array auf das Beispiel oben mit den Waffensystem anwenden (Es sei noch mal erwähnt, dass man auch einfache Zahlen anstatt Arrays nehmen könnte. Warum das nicht zu empfehlen ist sehen Sie bei der Variabelendefinition):

Var waffe_schaden[10];

Function main()
{
waffe_schaden[0] = 10;
waffe_schaden[1] = 20;
waffe_schaden[2] = 17;
waffe_schaden[3] = 14;
waffe_schaden[4] = 12;
waffe_schaden[5] = 52;
waffe_schaden[6] = 33;
waffe_schaden[7] = 75;
waffe_schaden[8] = 19;
waffe_schaden[9] = 7; //Hier ist die letzte gültige Variable
}

7.1 Vektoren
Ein Vektor ist ein Array mit 3 Variablen. Ein Vektor kann für folgende Dinge stehen:

Raumkoordinaten (x,y,z)

Drehwinkel

Farben (Rot, Grün, Blau)

Wenn man mit Vektoren Raumkoordinaten anspricht geht man wie folgt vor:

Var first_vektor[3]; //Vektor wird definiert

Function main()
{
first_vektor.x=10; //first_vektor[0]=10; würde das gleiche bedeuten.
First_vektor.y=20;
First_vektor.z=0;
}

Nun liegt, in diesem Fall, der First_vektor Vektor auf den Raumkoordinaten {10,20,0}.
Man kann genauso mit einen Vektor die drei Eulerwinkel (Pan,Tilt,Roll) und die 3 Farben red,green,blue mit einen Vektor ansprechen.
Es gibt nun noch eine Reihe von Vektor Anweisungen wobei ich hier nur die wichtigsten erwähnen möchte:

7.1.1 vec_set(vektor1,vektor2);
Vec_set übertrage alle Werte eines Vektors auf einen anderen Vektor.
Die Syntax von vec_set:

Vec_set(vec1,vec2);

Vektor1 hat nun den gleichen Inhalt wie Vektor2. Wenn Vec1 schon in vorhinein Werte beinhaltete werden die überschrieben.
Ein Beispiel:

Var vektor_1[3] = 5,2,1;
Var vektor_2[3];

Function main()
{
vec_set(vektor_2,vektor_1);
/* Dies hat die gleiche Auswirkung wie:
vektor_2.x = vektor1.x;
vektor_2.y = vektor1.y;
vektor_2.z = vektor1.z;
allerdings ist vec_set etwas schneller.
*/
}

7.1.2 vec_add(vektor1,vektor2);
Vec_add addiert vektor1 und vektor2. Das Ergebnis wird in Vektor1 geschrieben.
Beispiel:

Var vektor_1[3] = 5,2,1;
Var vektor_2[3] = 3,5,5;

Function main()
{
vec_add(vektor_2,vektor_1); //vektor2 beinhaltet jetzt 8,7,6.
/* Dies hat die gleiche Auswirkung wie:
vektor_2.x += vektor1.x;
vektor_2.y += vektor1.y;
vektor_2.z += vektor1.z;
allerdings ist vec_add etwas schneller.
*/
}

7.1.3 vec_sub(vektor1,vektor2);
Vec_sub zieht Vektor2 von Vektor1 ab. Das Ergebnis wird in Vektor1 geschrieben.
Wie immer ein Beispiel:

Var vektor_1[3] = 5,2,1;
Var vektor_2[3] = 3,5,5;

Function set_vektor
{
vec_sub(vektor_2,vektor_1); //vektor2 beinhaltet jetzt 8,7,6.
/* Dies hat die gleiche Auswirkung wie:
vektor_2.x -= vektor1.x;
vektor_2.y -= vektor1.y;
vektor_2.z -= vektor1.z;
allerdings ist vec_sub etwas schneller.
*/
}

7.1.4 vec_dist(vektor1,vektor2);
Vec_dist berechnet die Entfernung von zwei Vektoren und liefert sie zurück.

var vektor_1[3] = 0,0,0;
var vektor_2[3] = 10,0,0;

function set_vektor()
{
var a;
a = vec_dist(vektor_1,vektor_2);
//Nun ist in A die entfernung von Punkt1 zu Punkt2 gespeichert (in diesem Fall 10 Quants)
}

8. Lokale Variablen
Lokale Variablen sind eine spezielle Form von Variablen. Lokale Variablen werden innerhalb von Funktionen definiert und sind auch nur in dieser einen Funktion gültig.

Programmbeispiel:

Function main()
{
var a;
var b;
a=5; b=6;
}

Die Variablen A und B sind jetzt nur in der Funktion main gültig. Folgenden Fehler unbedingt vermeiden:

Function addiere()
{
a+=b;
}

Function main()
{
var a;
var b;
a=5; b=6;
addiere();
}

Dies würde eine Fehlermeldung hervorrufen da a und b in der Funktion addiere nicht gültig sind.

9. If-Else Unterscheidungen
Schnell kommt man in Programmen an die Stelle wo man gerne zwei Werte mit einander vergleichen will. Dafür gibt es die If Unterscheidung. Die korrekte Syntax von if ist:

If(Bedingungen)
{
//Wenn Bedinung wahr ist, führe das hier aus
}

In Worten ausgedrückt:

Wenn die Bedingung in der Klammer wahr ist, werden die Anweisungen in den geschweiften Klammern ausgeführt. Wenn nicht dann springt die Funktion bis zum Ende der Klammer.

In der Bedingung werden immer 2 Werte mit einander verglichen. Dazu gibt es jetzt verschiedene Operatoren:

Wert1 == Wert2 //Bedingung ist wahr wenn beide werte gleich sind
Wert1 >= Wert2 //Bedingung ist wahr wenn Wert1 größer oder gleich Wert2 ist
Wert1 > Wert2 //Bedingung ist wahr wenn Wert1 größer als Wert2 ist
Wert 1 < Wert2 // Bedingung ist wahr wenn Wert1 kleiner als Wert2 ist
Wert 1 <= Wert2 // Bedingung ist wahr wenn Wert1 kleiner oder gleich Wert2 ist
Wert 1 != Wert2 // Bedingung ist wahr wenn Wert1 ungleich Wert2 ist

Um das ganze noch mal an einen ganz konkreten Beispiel zu zeigen:

Function main()
{
var a=5; var b=10; //Definierung der Variablen
if(a==b)
{
//Dies hier wird nicht ausgeführt
}
if(a < b)
{
//Dies hier wird ausgeführt
}
if(a != b)
{
//Dies hier wird auch ausgeführt
}
}

Es gibt auch noch die Möglichkeit verschiedene if Bedingungen zu verknüpfen. Und zwar mit dem UND und den ODER Operator.
Wenn Sie z.B. wollen, dass der If Block ausgeführt wird wenn wert1 > 2 ist aber wert 1 auch kleiner als 10 ist müssen Sie das wie folgt schreiben:

If(wert1 < 10) && (wert1 > 2) { //tue das..

Auf Deutsch: Wenn Wert1 kleiner als 10 ist UND wert1 größer als 2 ist führe die Anweisung aus.
Die Oder Anweisung sieht so aus:

If(wert1 < 10) || ( wert1 > 2) { //tue das...

Wenn Wert1 kleiner als 10 ist ODER wert1 größer als 2 ist führe die Anweisung aus.
Diese Verknüpfung kann man mit so vielen Werten gleichzeitig machen wie man will.

Dies sollte die If Bedingungen hinreichend erklären.
Nun kommen wir zu den Else Bedingungen:
Die Else Bedingung wird ausgeführt wenn die If Bedingung falsch ist.

If(wert1 == 6)
{
//Anweisungen
}
else
{
//Anweisungen
}

In Worten:
Wenn 5 gleich 6 ist, führe die Anweisungen in den IF Klammern aus, wenn 5 nicht gleich 6 ist führe die else Bedingung aus.

10. Schleifen
Eine Schleife ist eigentlich vom Syntax ähnlich wie der von der If Bedingung. Eine Schleife wiederholt nur die Anweisungen in den geschweiften Klammern so lange bist die Bedingung wahr ist. Die If hingegen Anweisung überprüft die Bedingung einmal, führt vielleicht die Anweisung aus, und fährt dann einfach im Script fort.

Die Syntax einer Schleife:

While(Bedingung)
{
//mache das
}

In Worten:
Solange die Bedingung wahr ist führe die Anweisungen in den Klammern aus.
Ich will ihnen jetzt einmal ein Skriptbeispiel geben:

Function main()
{
var a; var b; //Definition von a,b
while(a <= 99)
{ //solange a kleiner gleich 99 ist
a+=1; //erhöhe a um 1
b = a; //setzte b auf a
}
}

Am ende dieses Skripts ist a und b 99!

Bei Schleifen kommt manchmal die Fehlermeldung „possible endless loop“. Das bedeutet, dass die Schleife öfter als 5000 mal ausgeführt wurde ohne das die Bedingung wahr wurde.

10.1 Wait und Sleep Befehle
Der Wait und der Sleep Befehl halten die Funktion die grade ausgeführt wird um eine bestimmte Zeit auf. Die Syntax von Sleep bzw. Wait:

Wait(Zahl);
Sleep(Zahl);

Wait(1); hält eine Funktion um eine Frame an.

Sleep(2); hält eine Funktion um genau 2 Sekunden an. Das heißt bei sleep wird die Zahl nicht in Frames sondern in Sekunden angegeben.

Wait kann man auch perfekt bei Schleifen benutzen.
Stellen Sie sich vor, Sie wollen eine Schleife endlos durchführen. Das ist zum Beispiel bei der Bewegung des Spielers der Fall. In diesem Fall setzt man an das Ende der Schleife ein Wait(1);
Hiermit pausiert die Engine diese Funktion einen Frame und führt sie danach wieder aus. Wenn Sie das Wait(1); weglassen würde die Engine die Funktion immer und immer wieder ausführen ohne eine Unterbrechung.

Im folgenden Beispiel wollen wir einen kleinen Counter erstellen der jede Sekunde eine Variable um 1 senkt.

Var counter;

Function counter_start
{
while(counter > 0)
{
counter -=1; //ziehe von counter 1 ab
sleep(1); //warte eine Sekunde
}
}

function main()
{
counter=100; //setzte counter auf 100
counter_start();
}

Hier müssen Sie noch beachten, dass wenn hinter dem Funktionsaufruf von counter_start(); weiterer Code kommen würde, der weiterhin ausgeführt worden wäre. Das liegt daran das die Engine mehrere Funktionen gleichzeitig ausführen kann!
Durch die Kommentare sollten Sie den Code verstanden haben.

11. Starter
Starter sind Funktionen die bei dem Programmstart aufgerufen werden. Sie müssen nicht durch die main() Funktion aufgerufen werden.
Ein Beispiel:

Starter starter_beispiel
{
//normale Funktion
}

12. Actions
Actions sind Funktionen mit der Besonderheit, dass man eine Action einer Entität in WED zuweisen kann.
Beispiel:

Action player_action
{
//Anweisungen
}

13. Parameter bei Funktionen
Manchmal wollen Sie Funktionen beim Aufruf bestimmte Werte überliefern. Die kann man über Parameter machen. Man kann bei einer Funktion maximal 4 Parameter überliefern.
Die Syntax:

Function paramterter_test(paramter1,parameter2,paramter3,paramter4)
{
//Anweisungen
}

Auf diese Parameter kann man dann in dieser Funktion, genauso wie bei lokalen Variablen, zugreifen. Die Werte der Parameter entsprechen denen bei dem Programmaufruf.

Function addiere(zahl1,zahl2)
{
return(zahl1+zahl2);
}

function main()
{
var a;
a=addiere(10,15); //a ist 25
}

In der oberen Funktion finden Sie jetzt ein Parameter das Sie noch nicht kennen und zwar return. Return liefert einen Wert zurück. Nach return wird die Funktion sofort beendet. Wenn Sie also noch nach der return Anweisung, Codes schreiben ist das der engine egal, weil Sie die Funktion gar nicht mehr ausführt. Sie müssen übrigens gar keinen Wert zurückliefern. Wenn Sie einfach nur wollen das die Funktion beendet wird müssen Sie nur
Return;
schreiben!

Sie können bei
a=addiere(10,15);
jeden beliebigen wert eingeben, auch Variablen. A beinhaltet nach der Berechnung immer Zahl1+Zahl2.

14. Dateiarten und Definieren von Dateien
Jetzt wollen wir lernen wie man Dateien definiert und welche Dateien 3D Gamestudio nutzen kann.

Dateien die 3D Gamestudio nutzen kann:

Bitmap Dateien ( *.bmp, *.pcx, *.tga)

Sound Dateien (*.wav, *.mid - folgende Dateitypen gehen nur ab der Commercial Edition: *.mp3,*.wma)

Video Dateien (*.avi, *.mpeg, *.jpg, *.png - Videos kann man nur ab der Commercial Edition abspielen)

Scriptdateien (*.wdl)

Levels (*.wmp für die Map editor file, *.wmb die beim Builden erstellte Datei. Die *.wmb Datei wird von Scripten geladen)

Dll Dateien (*.dll)

Die Dateien werden folgendermaßen definiert:

Typ name = <Dateiname.Dateiart>;

Dies nun an zwei Beispielen:

Bitmap Dateien:

Bmap name <Dateiname.Dateiart>;

Der Dateiname steht in einer spitzen Klammer, dann kommt ein Punkt, dann die Dateiart (pcx,tga,bmp).

Sound Dateien

Sound name <Dateiname.Dateiart>;

Die restlichen Dateiarten muss man nicht definieren, da man den Dateinamen direkt beim aufrufen in den Befehl eingibt.

15. Panels
Ein Panel kann viele nützliche Dinge tun. So kann man mit einen Panel Zahlenwerte und Bitmaps auf einem Bildschirm darstellen.

15.1 Aufbau eines Panels
Ein Panel baut sich anders auf als zum Beispiel eine Funktion. Der Grundaufbau ist wie folgt:

Panel name
{
//Inhalt
}

Name sollte nun klar sein (wenn nicht nach oben blättern), nur was ist jetzt der Inhalt eines Panels. Nun zum einen kann man natürlich die Position des Panels einstellen. Das geht wir folgt.

Panel name
{
pos_x = 0; pos_Y = 0;
}

Pos_X bzw. Y sind die Positionen auf den Bildschirm und werden in Pixeln angegeben. Ganz oben links in der Ecke ist sowohl Pos_x als auch Pos_y 0! Wenn man weiter nach rechts geht erhöht sich Pos_x, wenn man weiter nach unten geht erhöht sich Pos_Y. Die Grenzwerte sind jeweils:

Pos_x Grenzwerte: 0......Bildschirmauflösung X (in Pixeln. Also z.B. 1024 bei einer Auflösung von 1024*768)
Pos_y Grenzwerte: 0.....Bildschirmauflösung Y (natürlich auch in Pixeln).

Nun soll ja das Panel auf irgendetwas darstellen.
Am Anfang wollen wir uns mit einen einfachen schwarzen Bitmap zufrieden Stellen.
Erstellen Sie einen Ordner „Tutorial“.
Öffnen Sie ein Malprogramm und malen Sie ein schwarzes Bild mit der Dateigröße 1024*768. Speichern Sie das Bild in den Ordner Tutorial mit den Namen „Bild“ als PCX Datei ab.
Nun wollen wir unser erstes Script schreiben, dass man ohne Templates Starten kann.
Dazu erstellen Sie ein neues Level, erstellen einfach einen Medium Cube in ihm, builden das Level und speichern es als „tut_level.wmb“ in den oben erstellten Tutorial ab.

Jetzt öffnen Sie ihren persönlichen Script Editor und schreiben folgendes Script in ihren Script Editor:

Var video_mode=8; //Setzte Video_mode auf 8. Erklärung unten
Var video_depth=16; //Setzte Farbtiefe auf 16
Bmap schwarz_bmap = <Bild.pcx>; //Definiere das Bild „Schwarz_bmap“

Panel bild_pan
{
pos_x=0; pos_y=0; //Setzte Pos_x und Y auf 0
bmap=schwarz_bmap; //Weiße dem Panel das Hintergrundsbitmap Schwarz_bmap zu
}

function main
{
bild_pan.visible=on; //setzte das Bild auf sichtbar!
Load_level(“tut_level.wmb“);
}

Hier sind jede Menge neuer Befehle drinnen. Deshalb will ich einmal den Code Schritt für Schritt durchgehen.

Var video_mode=8;

Video_Mode ist eine Engine Variable. Diese Variable setzt die Auflösung. Hier alle Auflösungen:

320x240

320x240 (Defaultmodus für Flythrough)

320x400 (wird von einigen Adaptern nicht unterstützt)

400x300 (wird von einigen Adaptern nicht unterstützt)

512x384 (läuft nicht auf einigen Laptops)

640x480

800x600

1024x768 Ab Extra

1280x960 Ab kommerziell

1400x1050 Ab Professionell

1600x1200

Var video_depth=16;

Video_Depth ist genau wie Video_Mode eine vordefinierte Enginevariable. Video_Depth setzt die Farbtiefe. Diese Variable kann entweder den Wert 16 (16 Bit Farbtiefe) oder 32 (32 Bit Farbtiefe) haben.

Panel bild_pan
{
pos_x=0; pos_y=0; //Setzte Pos_x und Y auf 0
bmap=schwarz_bmap; //Weiße dem Panel das Hintergrundsbitmap Schwarz_bmap zu
}

Als erstes wird hier das Panel bild_pan definiert. Danach wird sowohl die X als auch die Y Position auf 0 gesetzt. Ganz am Ende wird dem Panel noch das Hintergrundsbild schwarz_bmap gegeben, was wir vorher definiert haben.

bild_pan.visible=on;

Diese Zeile macht das oben definierte Panel sichtbar.

Load_level(“tut_level.wmb“);

Dieser Befehl lädt ein Level. Hier mit den Namen tut_level.wmb! Eine genauere Beschreibung folgt später noch. Erst mal müssen Sie nur wissen was dieser Befehl macht.

Jetzt schreiben Sie den Code oben doch mal in ihre Scriptdatei und speichern Sie die Scriptdatei als „bild.wdl“. Nun öffnen Sie wieder ihr kleines Level und drücken Sie auf ->file ->map properties ->Load Script › laden Sie ihr Script

Drücken Sie jetzt RUN und siehe da. Das Bild wird auf den Bildschirm ausgegeben.

Nun ein Panel kann noch viel mehr als ein Hintergrundbild darstellen. Es kann unter anderem:

Variablen darstellen

Buttons darstellen, die eine Funktion ausführen wenn man auf Sie klickt

Slider darstellen (Eine Schiebefläche in der man eine Box von links nach rechts bzw. von oben nach unten bewegt um eine Variable zu verändern.)

Außerdem gibt es noch eine Menge Eigenschaften für Panels

15.2 Variablen darstellen (digits)
Eine Variable kann man über den Befehl digits (wörtlich übersetzt „Zahl, Ziffer“) darstellen. Die Syntax von digits ist relativ lang. Hier der komplette Syntax plus Erklärung:

Digits = pos_x,pos_y,Anzahl der Stellen, Font, Faktor, dargestellte Variable;

Pos_x = Die X Position der Zahl relativ zur X Position des Panels
Pos_y = Die Y Position der Zahl relativ zur Y Position des Panels
Anzahl der Stellen = Anzahl der Stellen die dargestellt werden (wenn dieser Wert 2 ist, aber
Die dargestellte Zahl 999 ist, ist die Dargestellte zahl 99 ( da eben nur 2
Ziffern dargestellt werden))
Font = Font mit dem die Zahl dargestellt wird
Faktor = mit diesen Faktor wird die Zahl bei anzeige multipliziert (normalerweise 1)
Dargestellte Variable = Die Variable die dargestellt wird.

Nun wollen wir einmal zusätzlich zu den Hintergrundsbild von oben noch den Counter mit grafischer Darstellung programmieren.

Var video_mode=8; //Setzte Video_mode auf 8. Erklärung oben
Var video_depth=16; //Setzte Farbtiefe auf 16
Bmap schwarz_bmap = <Bild.pcx>; //Definiere das Bild „Schwarz_bmap“

Var counter=100;
Font arial_font = “Arial”,0,20; /*Einzigst unbekannte Zeile. Wird unten erklärt*/

Function counter_start
{
while(counter > 0)
{
counter -=1; //ziehe von counter 1 ab
sleep(1); //warte eine sekunde
}
}

Panel bild_pan
{
pos_x=0; pos_y=0; //Setzte Pos_x und Y auf 0
digits=10,10,3,arial_font,1,counter; //definiere ein digit
bmap=schwarz_bmap; //Weiße dem Panel das Hintergrundsbitmap Schwarz_bmap zu
}

function main
{
bild_pan.visible=on; //setzte das Bild auf sichtbar!
counter_start();
Load_level(“tut_level.wmb“);
}

Die einzigst unbekannte Zeile ist:

Font arial_font = “Arial”,0,20;

Diese Zeile definiert den True Type font Arial mit Schriftgröße 20 Pixel.
Die 0 bedeutet das der Font normal ist. 1 wäre fett, 2 kursiv, 3 ist kursiv und fett.
Damit diese Zeile funktioniert müssen Sie mindestens A5.52 haben! In Versionen unter A5.52 sind True Type fonts nicht möglich
Hier müssen Sie *.pcx Fonts nehmen.

Nun haben wir einen laufenden Counter.

15.3 Buttons
Nun schauen wir uns auch wie bei digits erst einmal den Syntax an.

Button = pos_x,pos_y,Button Grafik1,Grafik2,Grafik3,Funktion1,Funktion2,Funktion3;

Hier sind jetzt jede Menge komische Sachen (wozu braucht man 3 Grafiken und 3 Funktionen?).
Deshalb schauen wir uns jetzt einmal alles an.

Pos_x = Die X Position der Zahl relativ zur X Position des Panels
Pos_y = Die Y Position der Zahl relativ zur Y Position des Panels
Button Grafik1 = Diese Grafik wird dargestellt, wenn die Maus über den Button ist und
Geklickt wird.
Button Grafik2 = Diese Grafik wird dargestellt wenn die Maus NICHT über dem Button ist.
Button Grafik3 = Diese Grafik wird dargestellt wenn die Maus ÜBER dem Button ist.
Funktion1 = Diese Funktion wird aufgerufen wenn auf den Button geklickt wird
Funktion2 = Diese Funktion wird aufgerufen wenn die Maus den Button verlässt.
Funktion3 = Diese Funktion wird aufgerufen wenn die Maus den Button berührt

Ein Beispiel für einen Button:

Bmap button_bmp = <button.pcx>;
Var a;

Function set_a_to_zero
{
a=0;
}

Panel bild_pan
{
pos_x=0; pos_y=0; //Setzte Pos_x und Y auf 0
digits=10,10,3,arial_font,1,counter; //definiere ein digit
button=10,30,button_bmp,button_bmp,button_bmp, set_a_to_zero,null,null;
bmap=schwarz_bmap; //Weiße dem Panel das Hintergrundsbitmap Schwarz_bmap zu
}

Sie sollte alles verstehen außer vielleicht die letzten beiden Funktionen. Hier steht: Null,null.
Das bedeutet das der Button keine Funktion ausführt wenn die Maus den Button berührt oder verlässt.

15.4 Slider
Ein Slider ist nichts anderes als ein Schieberegler der zur Eingabe von Variablen mit der Maus bewegt werden kann.
Es gibt zwei Arten von Slider. Den senkrechten und den Wagrechten. Sie haben aber eigentlich beide den gleichen Syntax:

Hslider = pos_x,pos_y,Breite des Schiebereglers in Pixeln,Reglerknopfbitmap,min,max,var;
Vslider = pos_x,pos_y,Höhe des Schiebereglers in Pixeln,Reglerknopfbitmap,min,max,var;

Hslider = horizontaler Slider
Vslider = vertikaler Slider.

Wie immer eine Erklärung aller Punkte:

Pos_x = Die X Position der Zahl relativ zur X Position des Panels
Pos_y = Die Y Position der Zahl relativ zur Y Position des Panels
Breite/Höhe des Reglers = Die Höhe oder Breite des Schiebereglers in Pixeln
Reglerknopfbitmap = Das Bitmap des Knopfes zum ziehen des Sliders mit der Maus.
Min = Minimaler Wert der Variable
Max = maximaler Wert der Variable
Var = benutze Variable

Ein kleines Beispiel:

Bmap slider_bmp = <slider.pcx>; //Breite des Sliders = 220 Pixel
Bmap knopf_slider = <knopf.pcx>;
Var slider_var;

Panel slider_pan
{
pos_x=0; pos_y=0;
bmap=slider_bmp; //Die Slidergrafik
hslider=100,100,220,knopf_slider,0,200,slider_var;
}

15.5 Sonstige Paneleinstellungen
Es gibt auch noch eine Reihe von FLAGS (Schalter). Dies sind bestimmte Einstellungen, mit denen man einstellen kann ob das Panel z.B. von Anfang an sichtbar ist.

Die Syntax solcher Flags:

Flags=einstellung1,einstellung2;

Es gibt viele solcher Einstellungen, die man einfach per „ , “ aneinander hängt. Hier alle Einstellungen:

Visible = Nur wenn dieses Flag gesetzt ist, erscheint das Panel von Anfang an auf dem Bildschirm (man muss es nicht in einer Funktion sichtbar machen.
Overlay = Ist dieses Flag gesetzt, wird die Farbe 0 (schwarz) der Panel-BMAP nicht gezeichnet.
Transparent= Ist dieses Flag gesetzt, so werden der Hintergrund des Panel und die Buttons halb durchsichtig über dem Bild angezeigt.

15.6 Layer (wörtlich übersetzt: Ebene)
Nun stellen Sie sich einfach mal vor Sie wollen 2 verschiedene Panels übereinander legen. Nun wollen Sie natürlich bestimmen welches Panel über den anderen liegt. Das geht mit den layer befehl. Syntax =

Layer = wert;

Einfach oder? Desto höhere die ebene ist, desto höher ist die ebene eines Panels.
Z.B. ein Panel mit den Layer Wert 5 liegt über einem Panel mit Layer Wert 2!

16. Texte
Manchmal will man auch Texte darstellen. Dazu müssen Sie als erstes wissen wie man einen String definiert.

16.1 Strings
Ein String ist eine Reihe von Zeichen. Das heißt, ein String speichert keine Werte sondern Zeichen. Strings definiert man ähnlich wie Variablen:

String new_string = “Hallo! Wie geht es dir”;

Zeilenumbrüche in Strings erreicht mit einem „\n“. Ein Beispiel:

String new_string = “Hallo!\nWie geht es dir?”; //wenn man diesen String ausgibt kommt folgendes heraus:
/*Hallo!
Wie geht es dir?*/

Man kann strings auch noch auf zwei weitere Arten definieren:

String new_string; //Ein string ohne Inhalt.
String new_string[50]; //Ein string mit 50 Leerzeichen

Noch eine wichtige Sache:
Strings können nicht einfach mit den = Operator gesetzt werden. Darüber aber später mehr.

16.2 Definierung eines Textes
Mit Texten ist man nun in der Lage diese Strings auf den Bildschirm zu bringen.
Die Syntax eines Textes:

Text name
{
//Einstellungen
}

Texte bauen sich ähnlich auf wie Panels.
Deshalb sollte auch folgendes Codebeispiel nicht so viel neues bringen:

String first_string = “Hallo”; //definiere einen String
Font arial_font = “Arial”,0,20;
Text first_text
{
pos_x=0; pos_y=100;
string=first_string; //weise first_text den string first_string zu
font=arial_font; //stelle den Text mit den font arial_font da
flags=visible;
}

Hier sehen Sie jetzt einen einfachen Text. Das meiste sollte sehr verständlich sein (durch die Kommentare). Es gibt allerdings ein paar neue flags die ich hier jetzt einmal erläutern werde:

center_x = Das setzen dieses Flags bewirkt, das der Text horizontal auf pos_x zentriert wird. Ist das Flag nicht gesetzt, wird der Text linksbündig ausgerichtet
center_y = Das setzen dieses Flags bewirkt, das der Text vertikal auf pos_y zentriert wird. Ist das Flag nicht gesetzt, wird der Text nach oben ausgerichtet
condensed = Das Setzen dieses Flag bedingt, dass der Text horizontal um 1 Pixel pro Zeichen ‘gestaucht’ wird. Insbesondere Kursivfonts sehen so besser aus
narrow = Wie CONDENSED, nur wird der Text noch weiter gestaucht
transparent = Ist dieses Flag gesetzt, so wird der Text halb durchsichtig angezeigt.
Visible = Der Text ist von Anfang an sichtbar
Shadow = schreibt True-Type Font Text mit schwarzem Schatten
Outline = schreibt True-Type Font Text mit schwarzem Rand um die Zeichen

Die einzelnen Flags werden per „ , “ aneinandergehängt.

Sie können ja mal mit den Text dort oben ein bisschen rumspielen und in unserem Tutorialscript einsetzten.

17. Handbuch
Das wichtigste an diesem Tutorial ist eigentlich das Sie das Handbuch bedienen können. Wenn Sie das können brauchen Sie keine Tutorials mehr.
Das aktuellste Handbuch bekommen Sie hier:

http://www.3dgs.org/3DGS_Manual.chm
Das Handbuch stammt von Tobias Runde.

Nun öffnen Sie einmal das Handbuch und gehen unter index. Dort haben Sie die komplette Befehlsliste von 3D Gamestudio.

Als Beispiel gehen Sie mal auf: sys_day

Ganz oben steht jetzt Die Erklärung.
Danach kommt der Werteberreich und meistens noch ein Beispiel oder Besonderheiten.

Noch ein paar Tipps:

Bei Befehlen mit dem Typ „read-only“ (so z.B. sys_day) können nicht verändert werden! (Man kann ja auch nicht den Systemtag verändern..)

Bei Rückgabewerte sehr ihr was die Funktion zurückliefert. So liefert z.B. bmap_width die Breite eines Bitmaps zurück.

18. Pointer
Ein wichtiges aber auch schweres Thema habe ich noch nicht behandelt. Zeiger.
Ein Zeiger zeigt wie der Name schon sagt auf eine Entität oder auf andere Typen.
Man definiert einen Zeiger folgendermaßen:

TYP* name;

Unter Typ muss einer von ein paar verschiedenen Möglichkeiten angegeben werden:

Entity (Zeiger auf eine Entität)

Bmap (Zeiger auf ein Bitmap)

Es gibt noch einige andere Möglichkeiten, aber die hier sind erst mal die wichtigsten.

Wenn Sie einen Entity Zeiger definieren müssen Sie diesen Zeiger noch eine Entität zuweisen.
Zeiger sind eigentlich nur dazu da, dass man in anderen Funktionen Werte einer Entität ändern kann! Ein Beispiel:

Entity* player;
Action player_act
{
player=my;
//…
}

/*Der My-Zeiger zeigt auf die Entität, die im Wed die jeweilige Action benutzt.*/

Player=my;

/*Hier wird der Zeiger Player auf my gerichtet. Wenn man nun von einer vollkommen anderen Funktion z.B. den Spieler transparent machen will macht man das wie folgt:*/

Entity* player;

Action player_act
{
player=my;
my.passable=on; /*Mit Hilfe des my Zeigers kann man auf Eigenschaften der
Entität zugreifen. Übrigens:
Player.passable=on;
Hätte die gleichen Auswirkungen (der Spieler wird
Passable) */

//…
}

function greife_zu
{
while(player==0) { wait(1); }
player.transparent=on; //greife auf den player Zeiger zu!
}

Sie müssen noch unbedingt beachten, dass der Zeiger gesetzt ist bevor Sie auf ihm zugreifen. Wenn Sie sich unsicher sind ob der Zeiger schon gesetzt ist unbedingt ein :
while(player==0) { wait(1); }
vor den Zugriff auf die Playereigenschaften schreiben (Ein Pointer ist 0 solange er nicht gesetzt ist). Wenn Sie das nicht machen werden Sie von der Engine eine Fehlermeldung bekommen weil sie versucht auf einen Zeiger zuzugreifen der nicht gesetzt ist.

Ich hoffe das dies den Mauszeiger weitestgehend erklärt.

19. Skills und Flags
Jede erstelle Entität in WED besitzt 99 Skills und 8 Flags. Ein Skill ist eigentlich nichts anderes als eine Variable, nur dass sie sozusagen die Eigenschaften von den Entitäten sind. Die ersten 20 Skills und alle 8 Flags kann man in Wed setzten. Flags sind in etwa das gleiche wie Skills außer, dass sie nur zwei Zustände einnehmen können. Und zwar 1 (on) und 0 (off).

Der Beispiel für Skill1:

Action player_act
{
my.skill1=10;
my.skill98=20;
my.flag2=on;
}

Es ist auch möglich Vektoren in Skills zu speichern. Dabei geht man wie folgt vor:

Action player_act
{
var local_array[3]=10,5,2; //Vektoren dürfen lokal definiert sein, Arrays nicht!
My.skill2=local_array;
//my.skill2=10;
//my.skill3=5;
//my.skill4=2;
}

Weil skill1 oder skill2 nicht besonders aussagekräftig sind kann man die Skillnamen mit Hilfe der define Anweisung verändern.

20. Define
Mit Define kann man Skills und Flags andere Namen geben oder aber auch Konstante definieren.

Ein einfaches Beispiel für Define:

Define geschwindigkeit,skill; //Geschwindigkeit und skill1 ist das selbe!!

Action player_act
{
my.geschwindigkeit=10; //my.skil1=10; würde das gleiche bewirken.
}

Wie aber bereits angedeutet kann man mit define auch Konstante definieren.
Dies funktioniert wie folgt:

Define test_define,10;

Function test
{
var a;
a+=test_define; //hat die gleiche Bedeutung wie a+=10;
}

21. Einfache Maussteuerung
In diesem Kapitel wollen wir eine einfache Maussteuerung realisieren.
Hierbei werden Sie wieder eine Menge neuer Befehle lernen.
Als erstes einmal der Code:

Bmap arrow = <arrow.pcx>;//Mausgrafik
Function mouse_fun
{
while(1)
{
mouse_map=arrow; //Maus bekommt die richtige Grafik
mouse_mode=1; //Maus wird aktiviert
mouse_pos.x = Pointer.x;
mouse_pos.y = Pointer.y;
wait(1);
}
}

function main()
{
mouse_fun();
//..
}

Nun gehen wir mal jeden Befehl, Schritt für Schritt durch.
Als erstes wird eine Grafik definiert, die später die Maus wird.
Danach definieren wir die Funktion mouse_fun und starten eine Schleife!
Als erstes bekommt die Maus die Grafik arrow per mouse_map.
Die Syntax von mouse_map ist:
Mouse_map = Bitmap;

Als nächstes wird mouse_mode auf 1 gesetzt. Das hat zur Folge das die Maus angeschaltet wird.
Danach setzten wir noch die Koordinaten der Maus auf Pointer.x bzw. Pointer.y! Pointer.X/Y sind die absoluten Maus Koordinaten in Pixeln. Wenn man die Koordinaten der Maus an Pointer.X/Y setzt, kann man die Maus völlig frei über den Bildschirm bewegen.
Man muss die Mausfunktion in eine Endlosschleife setzten, damit die Mausposition immer wieder, je nach Mausbewegung, verändert wird!

22. Reaktion auf Tastendrücke
Dass eine Funktion auf Tastendrücke reagiert, ist wirklich denkbar einfach.
Es gibt eine Variable für jede Taste auf der Tastatur. Diese Variable ist entweder 1 wenn die Taste gedrückt ist, oder null wenn sie nicht gedrückt ist.
Die Namen der Variablen kann man im Handbuch, beim suchen von „Tastenbelegung „ unter „Tasten & Statistik“ sehen.
Hier ist ein Beispiel für eine einfache Funktion die zwei verschiedene Dinge macht je nachdem welche Taste gedrückt ist.

Function react_to_key
{
var i;
while(key_any==0) { wait(1); } //solange keine Taste gedrückt ist warte
if(key_e==1) { I=10; } //wenn E gedrückt wird…
if(key_s==1) { I=5; } //wenn S gedrückt wird…
}

23. Events
Ein Event (wörtlich übersetzt „Ereignis“) kann von Entitäten benutzt werden. Ein Event ist nichts anderes als eine vom Programmierer geschriebene Funktion,
die ausgeführt wenn etwas bestimmtes mit dem Entity passiert. Zum Beispiel wenn die Entity von einem anderen Entity gerammt wird. Die grundsätzliche Syntax eines Events ist wie folgt:

my.event = function;

Function ist eine beliebige Funktion innerhalb ihres Scriptes.
Nun gibt es eine Reihe verschiedener Events. Ich werde hier die wichtigsten behandeln.

23.1 Event_Block
Event block wird ausgelöst wenn das Entiy einen Levelblock berührt. Damit dieses event ausgelöst werden kann muss allerdings noch enable_block auf on gesetzt sein.
Ein Beispiel:

Function event_funct
{
//tue das wenn das Entity einen Levelblock berührt
}

action event_act
{
my.enable_block = on; //mache das Entity sensitiv auf Blockberührungen
my.event=event_funct;
}

Wenn das Entity nun einen Block berührt wird die Funktion event_funct aufgerufen.

23.2 Event_Entity
Event Entity wird genauso aufgebaut wie Event_block, nur dass event_entity aufgerufen wird wenn z.B. der Spieler während der Bewegung ein anderes Model rammt.
Ein Codebeispiel:

Function event_funct
{
if(event_type == event_entity)
{
//tue das wenn das Entity ein anderes Entity berührt hat
}
if(event_tyle == event_block)
{
//tue das wenn das Entity einen Levelblock berührt
}
}

action event_act
{
my.enable_block = on; //mache das Entity sensitiv auf Blockberührungen
my.enable_entity = on; //mache das Entity sensitiv auf Entityberührungen
my.event=event_funct;
}

23.3 Event_Impact
Event_Impact bewirkt genau das gleiche wie Event_entity, nur dass event_block aufgerufen wird, wenn ein Model von einem anderen Model gerammt wird.

24. Splitten in mehrere WDL Dateien
Nehmen wir an Sie haben ein sehr großes Script und wollen dies auf mehrere Wdl Dateien splitten. In diesem Fall erstellen Sie eine neue Wdl Datei und kopieren den Code in die Datei.
Danach inkludieren Sie die Scriptdatei mit Hilfe des include Befehls. Die Syntax von include:

Include <dateiname.wdl>;

Normalerweise werden alle Scriptdateien ganz am Anfang des Hauptscriptes inkludiert.

25. Debuggen
Es kommt sehr oft in der Entwicklung eines Spiels vor, dass ein Script zwar startet aber nicht das tut was es soll. Wenn man trotz Suche keinen Fehler im Script findet, ist oft das Debuggen des Scriptes eine große Hilfe.

Beim Debuggen eines Scriptes wird das Spiel eingefroren und in der oberen rechten Ecke erscheint ein Text indem eine Codezeile Ihres Scriptes steht. Wenn Sie auf die Leertaste drücken, sehen Sie vor der Codezeile das interne Ergebniss der Engine.

Die Engine geht automatisch in den Debug-Mode, wenn Sie an einen Debug-Punkt (der von Ihnen selber definiert wird) im Script ankommt. Einen Debug-Punkt definieren Sie mit Hilfe des Befehls "breakpoint;". Wenn Sie diesen Befehl in ihr Script schreiben springt die Engine in den Debug-Mode sobald der Befehl ausgeführt wird. Ein Beispiel:

var a;
if(a==1) { breakpoint; } //wenn A eins ist, soll die Engine in den Debug Mode springen

Wenn Sie die Engine wieder in den normalen Mode bringen wollen, müssen Sie Strg+Leertaste drücken. Nun läuft die Engine bis zum nächsten breakpoint normal weiter. Wenn Sie wollen, dass überhaupt kein breakpoint mehr ausgeführt wird müssen Sie die ESC Taste drücken.

Wenn Sie wissen wollen was bestimtme Funktionen zurückliefern müssen Sie im Handbuch bei INDEX unter Rückgabewerte schauen.

Nützliche Informationen

26. Tricks und Hinweise
In diesem Kapitel zeige ich Ihnen ein paar kleine Tricks in WDL.

26.1 If Trick
Wenn Sie wollen, dass eine Bedingung wahr ist, wenn Wert1 gleich 1 ist gibt es 2 Möglichkeiten:

If(wert1 == 1) { //mache das...
//oder aber so
if(wert1) { //mache das...

Wenn Sie das so schreiben ist die Aussage automatisch wahr, wenn Wert1 den Wert 1 hat.

Es gibt noch einen zweiten "If Trick".

If(wert1 == 0) { //mache das...
//oder aber so
if(!wert1) { //mache das...

Wenn Sie die unter Möglichkeit benutzen, ist die Aussage wahr, wenn der Wert 0 ist.

26.2 While Trick
Der gleiche Trick lässt sich auch machen wenn Sie eine Endlosschleife machen wollen.

//entweder so:

while(1==1)
{
//tue das
wait(1);
}

//oder so:

while(1)
{
//tue das
wait(1);
}

Ist relativ logisch, da die Bedingung while(1) das gleiche Bedeutet wie die Bedingung while(1==1)

26.3 Hinweis bei Parametern bei Buttons
Funktionsparameter bei Buttons sind nicht möglich.

26.4 Layer
Layer können während der Laufzeit NICHT geändert werden. Hier müssen Sie zwei verschiedene Panels machen die Sie dann sichtbar bzw. unsichtbar machen.

26.5 Übersichtlichkeit
Versuche deine Scripts so übersichtlich wie möglich zu gestalten. Das hilft dir bei längern Codes enorm.

26.6 Klammern bei Events
Die Funktionsklammern bei my.event=function; unbedingt weglassen. Wenn diese Klammern geschrieben werden, hat das Entity gar kein Event.

26.7 Anzeigen von Skillnamen in WED
Sie haben einen Skill per define umbenannt und wollen, dass dieser Skill nun auch mit den richtigen Namen in Wed angezeigt wird? Nichts leichter als das.
Schauen Sie sich einfach das Beispielscript an:

Define leben,skill1;
Define armor,skill2;

//uses leben,armor
action player_act
{
//statt skill1,skill2 steht nun leben,armor in WED. Die Kommentarstriche bei uses unbedingt bestehen lassen.
//....
}

Nachdem Sie das //uses in Ihr Script eingefügt haben müssen Sie WED noch neu starten, damit die Änderungen übernommen werden.

27. Grundlegende Funktionen
In diesem Kapitel werden Sie noch einige Grundlegende Funktionen lernen.

27.1 String Befehle
Wie ich bei den Strings schon erwähnt habe kann man strings nicht einfach einen Inhalt durch den Zuweisungsoperator = zuweisen.
Daher gehe ich im folgenden noch mal auf ein paar String Befehle ein:

27.1.1 str_cpy(string1,string2);
Str_cpy kopiert String2 in String1. Wenn String1 schon Zeichen beinhaltet werden diese überschrieben. Ein einfaches Beispiel:

String test_str = “Test the String”;

Function main
{
str_cpy(test_str,”Hallo”); //test_str beinhaltet nun “Hallo”
}

27.1.2 str_trunc(string1,zahl);
Str_trunc schneidet so viele Zeichen vom ENDE des Strings ab, wie in Zahl angegeben wurde. Ein Beispiel:

String test_str = “Test the String”;

Function main
{
str_trunc(test_str,5); //test_str beinhaltet nun “Test the S”
}

27.1.3 str_clip(string1,zahl);
Str_clip funktioniert genauso wie str_trunc nur das Str_clip die Zeichen vom ANFANG des Strings abschneidet.

String test_str = “Test the String”;

Function main
{
str_clip(test_str,5); //test_str beinhaltet nun “the String”
}

27.1.4 str_cmp(string1,string2);
Str_cmp vergleicht 2 Strings unter Berücksichtigung von Groß und Kleinschreibung und liefert 1, wenn string2 und string1 gleich sind. Str_cmpi vergleicht 2 Strings ohne Berücksichtigung von Groß und Kleinschreibung. Str_cmpni vergleicht 2 Strings und liefert 1 wenn String2 in String1 vorkommt.

String test_str = “Hello World”;
String zweiter_str = “Hello”;

Function main
{
var a;
a = str_cmp(test_str,zweiter_str); //A ist null
a = str_cmpi(test_str,”HeLlO wOrLd”); //A ist eins
a = str_cmpni(test_str,”Hello”); //A ist eins
}

Für weiter Befehle schauen Sie im Handbuch unter str_ nach.

27.2 Entity Eigenschaften
Eine Entität hat viele verschiedene Eigenschaften auf die man mithilfe des My Pointers innerhalb der Action oder mit einem zugewiesenen Pointer außerhalb der Action zugreifen kann.
Ich werde nun auf die wichtigsten und häufigst benutzen Eigenschaften eingehen.

27.2.1 Pan Tilt Roll
Man kann eine Entität natürlich rotieren. Dies funktioniert mit den Eigenschaften Pan – Tilt – Roll.
Pan dreht um die Z, Tilt um die Y und Roll um die X Achse. Alle 3 Eigenschaften haben einen Wertebereich von 360. Die Werte werden in Grad angegeben.
Ein Beispiel zum ständigen rotieren einer Entität:

Action rotate_me
{
while(1)
{
my.pan += 3; //Drehe die Entität um die Z Achse mit der Geschwindigkeit von 3 Grad pro Frame
wait(1);
}
}

27.2.2 Passable
Mit Passable kann man eine Entität passable machen. Der Wertebereich ist 1 (on) und 0 (off). Ein Beispiel:

Action gegner
{
my.passable=on;
}

27.2.3 Visible
Mit Visible kann man eine Entiät sichtbar bzw. unsichtbar machen. Der Wertebereich ist genau wie bei passable 1(on) oder 0 (off).

Action unsichtbar_act
{
my.visible=off;
}

27.2.4 Transparenz
Wenn Sie Transparent auf ON schalten wird ein Entity halb durchsichtig.

Action transparent_act
{
my.transparent=on;
}

27.2.4.1 Alpha
Sie können den Wert wie viel ein Entity durchsichtig ist auch noch durch Alpha verändern. Bei Alpha 0 ist das Entity unsichtbar. Bei Alpha 100 ist das Entity voll sichtbar.
Transparent muss auf ON gesetzt sein wenn Sie Alpha benutzen wollen.

Action alpha_test
{
my.transparent=on;
my.alpha=75; //mache die entity ¾ sichtbar
}

27.3 Sonstige Befehle
27.3.1 Trace
Da viele Einsteiger und Fortgeschrittene den Befehl Trace nicht verstehen werde ich ihn hier genauer erklären.

Man kann sich Trace ganz einfach so vorstellen, dass dieser Befehl einen "Strahl" von einem Punkt zu einem anderen Punkt sendet um zu testen ob ein Hindernisse dazwischen ist. Wenn ein Hinderniss dazwischen ist, wird der Abstand von Punkt1 zu dem Hinderniss zurückgegeben. Wenn kein Hinderniss in Weg ist wird 0, wenn der Startpunkt von Trace(Punkt1) in einem festen Objekt wie z.B. einem Modell ist wird ein Wert kleiner als Null zurück geliefert. Die Syntax werden Sie sich sicher schon vorstellen können:

result=trace(Punkt1,Punkt2);

Punkt1 und Punkt2 sind natürlich Vektoren.

Nun gibt es noch eine Menge Modifizierungsmöglichkeiten und weitere Rückgabewerte von Trace. Wenn Sie z.B. wollen, dass Trace Modelle ignoriert, müssen Sie trace_mode verändern. Trace_Mode beinhaltet den Modus mit dem Sie Tracen. Ein Beispiel sehen Sie hier:

trace_mode=Ignore_Maps+Ignore_Passable; //Trace soll Passable Blöcke/Entitäten und Map Entities ignorieren
result=trace(Punkt1,Punkt2);

Die verschiedenen Trace_Modes werden einfach per "+" aneinnander gehängt. Alle Trace Modes finden Sie im Handbuch unter "trace". Nun modifiziert Trace auch noch ein paar andere Variablen/Vektoren bzw. Strings.

Zum einen wird der String tex_name. In diesem String steht nacht der Trace anweisung (Natürlich nur wenn Trace NICHT null zurük liefert) der Texturname des getroffenen Blocks. Wenn ein Modell oder ein Map Entity getroffen wurde steht in tex_name der Dateiname von diesem Modell/Map Entity. Tex_name wird nur modifiziert wenn im Trace_mode "Scan_Texture" aktiviert ist.

Der Vektor Target wird nach Trace an den Punkt gesetzt an dem das Hinderniss ist.

Alle veränderten Werte können Sie im Handbuch unter Trace, "Modifiziert" nachlesen.
Benutzen Sie Trace nicht zu oft, da sonst die Framerate sehr darunter leiden wird. Trace ist ein sehr langsamer Befehl.

27.3.2 Snd_play
Mit Snd_play können sie Musikdateien abspielen. Die Syntax von Snd_play ist wie folgt:

snd_play("Dateiname.wav",Lautstärke,Balance);

Mit snd_play können nur Wav Dateien wiedergegeben werden. Mit Balance kann man den Sound bei Stereo Systemen zum linken (Negative Werte) bzw. zum rechten(positive Werte) Lautsprechen bewegen. Bei 0 wird der Sound normal abgespielt.

Mit snd_loop kann man einen Sound endlos abspielen. Die Syntax ist die gleiche.

27.3.3 Temp und Result
Temp ist ein Vektor, der jeden Frame einen anderen Wert beinhaltet. Temp ist von der Engine schon vordefiniert und muss nicht mehr initialisiert werden. In Temp darf man keine Werte über mehrere Frames speichern.

Result ist eine interne Test Variable die fast von jeder Anweisung gesetzt wird.

28. Wichtige Befehle
Suchen Sie im Handbuch nach diesen Befehlen. Anhand dieses Tutorials sollten Sie in der Lage sein die Beschreibung zu verstehen:

ent_move bzw. C_move (zum bewegen von Entitäten)

vec_ Anweisungen (zum manipulieren von Vektoren)

inkey (zum direkten eingeben in Strings)

--------------------------------------------------------------------------------

29. Abschluss
Ich hoffe, dass Sie durch dieses Tutorial einiges gelernt haben und jetzt mit den Handbuch umgehen können. Bei Fragen über dieses Tutorial bitte bei Triple-X@hawkgames.de oder bei mir unter ICQ: 170911701 melden.

Bewertung Anzahl
6
100,0 %
2 Bewertungen