Syntax:
Obwohl Gugli bereits einen kleinen
Thread für die Syntax von Maniascript erstellt hat, werde ich diese zusammen mit den Grundlagen einer Programmiersprache hier noch einmal wiederholen – Nur, um sicherzugehen, dass ihr alle dieses Tutorial versteht.
Variablen:
Das wichtigste in Programmiersprachen sind Variablen. Eine Variable hat einen Typ (Zahl, Text, Zustand, …), einen Namen und einen damit verbundenen Wert. Ich kann in einer Variable einen Wert speichern und später auf diesen Wert zugreifen, indem ich einfach den Namen dieser Variable benutze. Während der Laufzeit (Die Zeit, während der das Skript ausgeführt wird) kann ich die Werte ändern (=> Variabel

) und somit beispielsweise auf Eingaben reagieren.
Es gibt verschiedenen Variablen-Typen: (Man spricht auch von "Datentypen")
1.) Integer
Ein
Integer ist einen ganzzahlige Zahl, d.h. sie besitzt keine Kommastellen. Ein
Integer könnte beispielsweise die Werte
2,
-54,
19274 oder
0 besitzen.
2.) Real
Ein
Real ist eine reelle Zahl, kann also Kommastellen besitzen. Wie es in Programmiersprachen üblich ist, werden die Vorkommastellen mit den Nachkommastellen durch einen Punkt
. getrennt und nicht durch ein Komma
,. Mögliche Werte wären also
5.2,
9123.1234 oder
-0.01.
 | Hinweis: 4. Ist ein Real und kein Integer, da es einen Punkt besitzt! Ebenso ist 3.0 ein Real. Sobald ein Punkt enthalten ist, deutet dies auf mögliche Nachkommastellen hin, weshalb Maniascript diese Werte als Real erkennt. |
3.) Boolean
Viele von euch werden schon das eine oder andere Mal den Begriff "Boolscher Wert" gehört haben. Die Grundidee ist relativ simpel – Ein
Boolean ist ein Zustand mit 2 Möglichkeiten: Wahr oder falsch, ja oder nein, richtig oder falsch. Am häufigsten wird die Wahr/Falsch-Symbolik verwendet, weshalb man in Programmiersprachen die englischen Begriffe true (wahr) und false (falsch) dafür verwendet. In Maniascript werden diese im Gegensatz zu Java oder PHP großgeschrieben!
Die einzigen beiden Möglichkeiten für einen Wert eines
Booleans sind also:
True oder
False.
4.) Text
Der Name sollte selbsterklärend sein.

In einem
Text wird eine Reihe an Zeichen gespeichert – Dargestellt wird ein
Text in Maniascript durch umschließende doppelte Anführungszeichen.
"
"Hallo! Ich bin destro." ist also ein
Text. Genauso wären auch
"0",
"67.2" oder
"True" Texte.

(Hier lässt sich schon ein kleines Problem erahnen: Wie soll man doppelte Anführungszeichen in Texten darstellen? Ganz einfach: Man "escapet" sie – Dies geschieht durch ein Voranstellen eines Backslashes
\. Befindet sich ein Backslash vor einem Zeichen, so bekommt dieses eine neue Bedeutung, je nachdem um welches Zeichen es sich handelt. So ist \" ein Anführungstrich, \n ein Zeilenumbruch und \\ ein Backslash. Der Inhalt
Destro sagt: "Hallo!" würde also als
Text so aussehen:
"Destro sagt: \"Hallo!\"")
Datentypen für Fortgeschrittene
Neben diesen simplen Datentypen bietet Maniascript auch ein wenig "fortgeschrittenere" Datentypen an - Diese können euch sehr hilfreich sein, vielleicht seid ihr eines Tages auch auf sie angewiesen.
Sich diesen Teil durchzulesen, kann sicherlich nicht schaden - Doch, falls ihr wirklich nur die Grundlagen von Maniascript beherrschen wollt, reichen euch (genauso wie den Codebeispielen in diesem Tutorial) die simplen Datentypen völlig aus.
Spoiler: Anzeigen...
5.) Enum
6.) Vec2, Vec3 (Vektoren)
7.) Int3
 | TODO: Fortgeschrittene Datentypen erklären |
Deklaration / Erstellen einer Variable:
Damit man eine Variable verwenden kann, muss diese natürlich erst einmal erstellt werden – Man spricht vom "Deklarieren" einer Variable. In Maniascript geschieht dies durch das Schlüsselwort
declare, gefolgt vom Variablentyp (Siehe oben) und dem Variablennamen.
Würde ich also eine Variable vom Typ
Integer (Ganzzahl) mit dem Namen
anzahlSpieler (und vorerst noch keinem genauen Wert) erstellen wollen, müsste ich folgenden Code schreiben:
declare Integer anzahlSpieler;
Hier lässt sich auch gleich ein weiteres Merkmal einer Programmiersprache erkennen – Man muss ihr sagen, ab wo der aktuelle "Befehl" zu Ende ist (Es wird ein Befehl nach dem anderen ausgeführt

). Dies geschieht üblicherweise, so auch in Maniascript, durch ein Semikolon
;. Deshalb muss nach jedem Befehl (was aber nicht jede Zeile bedeutet!) ein Semikolon stehen.
Würde ich der Variable
anzahlSpieler nun auch noch gleich einen Wert zuweisen wollen (Fachbegriff: Initialisieren), z.B.
12, würde das folgendermaßen aussehen:
declare Integer anzahlSpieler = 12;
Variablen weißt man Werte durch den Operator
= zu. (Ein Operator ist ein Zeichen, was in der jeweiligen Programmiersprache einen spezielle Bedeutung besitzt - So bedeutet das =-Zeichen die Zuweisung eines neuen Wertes). Ich könnte den Wert nun irgendwo später im Code ändern durch:
anzahlSpieler = 4;
 | Hinweis: Beachtet hier, dass ich das declare nicht mehr benötige – Dieses brauche ich nur an einer einzigen Stelle und zwar dort, wo die Variable erstellt wird. Anschließend reicht der Variablenname. |
Die beiden folgenden Codes würden also exakt das gleiche auslösen:
declare Integer anzahlSpieler = 12;
declare Integer anzahlSpieler;
anzahlSpieler = 12;
 | Hinweis: Variablen haben in Maniascript immer einen Wert – Wurde noch kein genauer Wert zugewiesen, so wird ein Standardwert für den jeweiligen Variablen-Typ verwendet.  |
Rechenoperatoren:
In Maniascript lässt sich natürlich wie in jeder Programmiersprache auch rechnen – Dies kann entweder direkt mit Zahlen, aber auch mit Variablen, die Zahlen gespeichert haben, geschehen.
Folgende Beispiele würde der Variable
anzahlSpieler (Die an diesem Punkt schon exisitiert) den Wert
10 zuweisen:
Addition (Plus)
anzahlSpieler = 8 + 2;
Substraktion (Minus)
anzahlSpieler = 13 - 3;
Multiplikation (Mal nehmen)
anzahlSpieler = 2 * 5;
Division (Teilen)
anzahlSpieler = 40 / 4;
Verwendung von Klammern
anzahlSpieler = (2 + 3) * 2;
 | Hinweis: Die Zeichen +, -, *, /, ( und ) sind ebenso wie = Operatoren, da sie eine spezielle Bedeutung in Maniascript-Ausdrücken haben. |
Man kann, wie bereits erwähnt, aber auch Variablen in die Berechnung mit einbeziehen:
declare Integer faktor = 5;
anzahlSpieler = 2 * faktor;
Im oberen Beispiel wird eine Variable mit dem Wert
5 erstellt und diese anschließend mit
2 mulitpliziert. Das Produkt wird der Variable
anzahlSpieler zugewiesen.

Dieses Verwenden von Variablen ist sehr nützlich, da man so auch die alten Werte einer Variable verwenden kann. Folgender Code würde den Wert von
anzahlSpieler um
1 erhöhen:
anzahlSpieler = anzahlSpieler + 1;
Zu dem Zeitpunkt der Berechnung besitzt
anzahlSpieler noch den alten Wert – Dieser wird mit
1 addiert und die Summe wieder in
anzahlSpieler gespeichert.
Logische Operatoren:
Bisher haben wir uns nur mit "normalen" Rechnungen beschäftigt - Zwei Zahlen wurden verrechnet und ergaben eine neue Zahl. Jedoch gibt es auch die sogenannten "logischen Operatoren", die einen
Boolean zurückliefern.

Dabei kann man die Bedeutung der Operatoren so interpretieren, als ob sie eine Bedingung haben, die die verrechneten Werte erfüllen müsen, damit das Ergebnis
True entspricht. Ist diese Bedingung nicht erfüllt, wird
False zurückgegeben:
| Operator | Bedingung für True | Wertetabelle |
| < (Kleiner) | Der erste Wert muss kleiner als der zweite sein. | -4 < 23 = True
145 < 9253 = True
3 < 2.8 = False |
| <= (Kleiner gleich) | Der erste Wert muss kleiner oder gleich dem zweiten sein. | 71 <= 0.56 = False
6 <= 6 = True
842 <= 21091 = True |
| == (Gleich) | Der erste Wert muss gleich dem zweiten sein. | 51 == 51 = True
451 == 0 = False
9 == 9.0 = True |
| != (Ungleich) | Der erste Wert muss ungleich dem zweiten sein. | 15.9 != 15.9 = False
28 != -6 = True
515 != 33 = True |
| >= (Größer gleich) | Der erste Wert muss größer oder gleich dem zweiten sein. | 99 >= 8 = True
63 >= 723 = False
0.002 >= 0.002 = True |
| > (Größer) | Der erste Wert muss größer als der zweite sein. | 2 > 1 = True
15.01 > 7 = True
4 > 11 = False |
| && (AND) | Beide Werte müssen True ergeben. | False && False = False
True && False = False
False && True = False
True && True = True |
| || (OR) | Mindestens einer der Werte True ergeben. | False || False = False
True || False = True
False || True = True
True || True = True |
| ! (NOT) | (Besitzt nur 1 Operanden => Unärer Operator)
Der Wert muss False ergeben. | ! True = False
! False = True |
 | Hinweis: Logische Operatoren, deren Werte als Booleans interpretieren (&&, ||, !), nennt man auch "Boolsche Operatoren".  |
Arbeiten mit Text-Variablen:
Mit Variablen vom Typ
Text lassen sich selbstverständlich keine grundlegenden Berechnungen wie Multiplikationen durchführen.

Allerdings gibt es auch hier ein paar Möglichkeiten.
Da wäre zum Beispiel der
^-Operator. Mit ihm lassen sich Werte auf Textebene "aneinander knüpfen" (Also keine Addition im mathematischen Sinne – Die Texte bzw. Werte werden einfach aneinander gehängt):
declare Text begruessungsAnfang = "Hallo ";
declare Text vollstaendigeBegruessung = begruessungsAnfang ^ "destro";
Der Inhalt der Variable
vollstaendigeBegruessung würde nach Ausführung dieses Codes folgenden Inhalt haben:
"Hallo destro"
Aber nicht nur
Texte lassen sich aneinander hängen – Ihr könnt ebenso andere Datentypen, z.B. Zahlen, in den Text einarbeiten:
declare Text nachricht = "Das doppelte von " ^ 5 ^ " ist " ^ (5*2);
Dieser Code würde folgenden Wert in der Variable
nachricht speichern:
"Das doppelte von 5 ist 10".
Kommentare:
Oft ist ein spezieller Codeteil sehr kompliziert, so dass man einen Kommentar hinterlassen will, um sich selber oder auch andere nicht zu verwirren und lange Sucharbeit zu verhindern. Ebenso könnte man seinen Namen gerne im Code hinterlassen oder das Datum, wann der jeweilige Codeabschnitt zum letzten Mal bearbeitet wurde. In diesem Fall bieten sich Kommentare an – Sie werden von Maniascript einfach ignoriert und auf keinen Fall in irgendeiner Weise ausgeführt.
Einzeilige Kommentare beginnen wie auch in anderen Programmiersprachen mit zwei Slashes
// und erstrecken sich bis zum Zeilenende:
//Hallo – Ich bin ein Kommentar
declare Integer anzahlSpieler = 5; //Ich kann auch hinter einem Befehl stehen
//anzahlSpieler = 8;
Der Wert von
anzahlSpieler würde nach Ausführung dieses Codes selbstverständlich
5 betragen und nicht
8, da der untere Befehl als Kommentar gekennzeichnet wurde und somit gar nicht erst beachtet geschweige denn ausgeführt wird.
Falls ihr vorhabt, einen längeren Kommentar zu schreiben und diesen nicht in eine Zeile quetschen wollt, könnt ihr einen mehrzeiligen Kommentar verwenden. Ihr markiert mit
/* den Anfang des "Kommentarblocks" und mit
*/ dessen Ende:
/*Ich bin ein mehrzeiliger
Kommentar. Ich höre daher erst hier auf

*/
Mehrzeilige Kommentare sind zudem hilfreich, um längere Codepassagen nicht ausführen zu lassen (z.B. bei der Fehlersuche) – Man spricht vom "auskommentieren":
declare Integer anzahlSpieler = 4;
/*anzahlSpieler = 5;
anzahlSpieler = anzahlSpieler + 1;*/
Nach Ausführung des Codes würde der Wert von
anzahlSpieler somit immer noch
4 betragen.
Funktionen:
Mithilfe von Funktionen lassen sich beliebig lange Programmabläufe zusammenfassen und mit einem einem einzigen Befehl aufrufen. Funktionen haben einen Namen und können zudem einen Rückgabewert besitzen - Dies müssen sie allerdings nicht.

Jedoch muss dies eindeutig deklariert werden, entweder durch den Datentyp des Rückgabewertes (
Integer,
Boolean,
Text, …) oder durch das Schlüsselwort
Void (Englisch: Leer, Nichts), falls kein Wert zurückgegeben wird. Der Programmablauf einer Funktion bzw. der Code, den sie ausführen soll, wird in einem "Codeblock" (siehe voriges Kapitel: Codeblock-System

) in geschwungenen Klammern
{...} zusammengefasst. Eine simple Funktion wird folgendermaßen deklariert:
Void meineFunktion(){
//Hier kann ein beliebig langer Programmablauf stehen
}
Die obere Funktion besitzt keinen Rückgabewert (
Void) und heißt meineFunktion - Diese Deklaration an sich führt noch keinen Code aus - Im späteren Programmablauf kann man schließlich über den Funktionsnamen mithilfe dieses Befehls den inneren Code der Funktion ausführen lassen:
meineFunktion();
Wie sich hier bereits erkennen lässt, eignen sich Funktionen sehr gut, um sich oft wiederholende Codeabschnitte zusammenzufassen. Eine mögliche Korrektur dieses Codes muss dann anschließend nur noch an einer Stelle getätigt werden.

Zudem dienen Funktionen der Lesbarkeit des Codes, speziell für Funktionen und Variablen gilt es, aussagekräftige Namen zu finden – Nicht zu kurz, nicht zu lang, keine falschen Aussagen gebend, präzise, … gar nicht so leicht, aber es ist noch kein Meister vom Himmel gefallen.

Trotzdem kann es nicht schaden, euren Funktionen von Anfang an passende Namen zu geben.
Funktionsparameter:
Oft tauchen im Code mehrere Stellen auf, die fast identisch sind, sich jedoch in kleinen Details unterscheiden. Beispiele:
anzahlSpieler = anzahlSpieler + 5;
irgendeineFunktion();
anzahlSpieler = anzahlSpieler + 8;
irgendeineFunktion();
declare Integer zaehler = 3;
anzahlSpieler = anzahlSpieler + zaehler;
irgendeineFunktion();
willkommensNachricht = "Hallo destroflyer";
willkommensNachricht = willkommensNachricht ^ ", Marcel";
willkommensNachricht = willkommensNachricht ^ ", Alinoa";
Wie sich erkennen lässt, passiert hier im Grunde mehrmals das gleiche. Allerdings könnte man einen solchen Ablauf nicht in eine "normale" Funktion einfügen und diese mehrmals aufrufen, da sich die einzelnen Codestücke minimal unterscheiden – Und zwar in den verwendeten Werten.
Die Lösung ist denkbar einfach: Irgendwie muss der Funktion, ein Wert übergeben werden, den diese anschließend weiterverarbeiten kann. Solche Werte nennt man "Parameter" einer Funktion.
(Im ersten der oberen Beispiele würde ich also z.B. eine Funktion namens
anzahlSpielerErhoehen schreiben, die den benötigten Wert übergeben bekommt, diesen mit der Variable
anzahlSpieler addiert und anschließend die Funktion
irgendeineFunktion aufruft)
Funktionsparameter werden zwischen den runden Klammern
(...) nach dem Funktionsnamen deklariert. Dabei steht zuerst der Datentyp, gefolgt von einem Namen, über den der Code im inneren der Funktion auf diesen Wert zugreifen kann.
Unsere Beispielfunktion soll 1 Parameter vom Typ
Integer besitzen – Einen Rückgabewert braucht sie nicht (
Void). Diese Funktion sähe so aus:
Void funktionMitParameter(Integer meinParameter){
//Hier kann die übergebene Variable additionsWert verwendet werden
}
Die Funktion kann nun durch die Variable
meinParameter auf den übergebenen Wert zugreifen. (Die Namen der Parameter können natürlich frei gewählt werden

)
Doch wie sieht nun der Aufruf der
funktionMitParameter-Funktion aus? Die Parameter werden wie in der Deklaration in den runden Klammern
(...) angegeben:
funktionMitParameter(5);
declare Integer zaehler = 21;
anzahlSpielerErhoehen(zaehler);
Selbst der Wert einer Variable kann problemlos als Parameter übergeben werden, solange es sich um den gleichen Datentyp handelt. (In diesem Fall ist sowohl die Variable
zaehler als auch der benötigte Funktionsparameter vom Typ
Integer)
Funktionen können selbstverständlich beliebig viele Parameter haben – Diese werden innerhalb der runden Klammern durch Kommata
, voneinander getrennt:
Void meineFunktion(Integer irgendeineZahl, Boolean einZustand, Real eineKommazahl){
//Code innerhalb der Funktion
}
Der Aufruf sieht dementsprechend folgendermaßen aus:
meineFunktion(5, True, 22.1);
 | Hinweis: Funktionen können im Code nur dann aufgerufen werden, wenn sie bereits vorher deklariert wurden. |
Rückgabewerte:
Wie bereits erwähnt, können Funktionen auch Werte zurückliefern – Dies ist vor allem bei Berechnungen hilfreich: Der Funktion wird einer oder mehrere Werte übergeben, diese führt die Berechnung aus und gibt das Ergebnis zurück.

Ich werde dies am Beispiel einer einfachen Funktion demonstrieren, die eine Zahl (Typ:
Integer) als Funktionsparameter übergeben bekommt, diese quadriert und das Ergebnis (Typ:
Integer) zurückliefert. Ich nenne diese Funktion
quadrieren – Die Deklaration sähe wie folgt aus:
Integer quadrieren(Integer zahlZumQuadrieren)
Durch den Datentyp
Integer vor der Funktion wird festgelegt: Diese Funktion liefert immer (!) einen Wert vom Typ
Integer zurück. Innerhalb der Funktion erstellen wir vorerst eine Variable, in der wir das Quadrat speichern, nennen wir sie
quadrat:
//Dieser Code befindet sich innerhalb der Funktion
declare Integer quadrat = zahlZumQuadrieren * zahlZumQuadrieren;
Auch hier lässt sich sofort erkennen: Der Code greift auf den übergebenen Funktionsparameter
zahlZumQuadrieren zu und multipliziert diesen mit sich selbt (Quadrieren

) – Das Ergebnis wird in der Variable
quadrat gespeichert.
Nun erfolgt die eigentliche Rückgabe des Wertes. Dies geschieht durch das Schlüsselwort
return:
//Dieser Code befindet sich innerhalb der Funktion
return quadrat;
Hier können wir direkt die Variable
quadrat zurückgeben – Wir könnten allerdings auch direkt das Ergebnis der Multiplikation zurückgeben und uns den Zwischenschritt mit der Variable sparen.

Der gesamte Code der Funktion
quadrieren würde somit so aussehen:
Integer quadrieren(Integer zahlZumQuadrieren){
declare Integer quadrat = zahlZumQuadrieren * zahlZumQuadrieren;
return quadrat;
}
Aber wie lässt sich dieser Rückgabewert nun verarbeiten? Ganz einfach – Man kann den Aufruf der Funktion direkt als Wert benutzen:
declare Integer quadratVonDrei = quadrieren(3);
Überall, wo ein Wert stehen kann, könnt ihr die Funktion verwenden – Selbst Verschachtelungen (Rückgabewert als neuen Parameter benutzen) ist möglich:
declare Integer dreiHochVier = quadrieren(quadrieren(3));
Gültigkeitsbereich von Variablen:
Innerhalb einer Funktion könnt ihr problemlos Variablen auslesen und verändern - Doch dies ist nur mit Variablen möglich, die in dieser Funktion deklariert wurden. Ein kleines Beispiel, um dies zu verdeutlichen:
Void spielerAnzahlUmEinsErhoehen(){
anzahlSpieler = anzahlSpieler + 1;
}
Void meineFunktion(){
declare Integer anzahlSpieler = 0;
spielerAnzahlUmEinsErhoehen();
}
Später führe ich an einer anderen Stelle im Code folgenden Befehl aus:
meineFunktion();
Auf den ersten Blick würde man denken, dass die Variable
anzahlSpieler erstellt wird, und ihr Wert anschließend durch den Aufruf von
spielerAnzahlUmEinsErhoehen um
1 erhöht wird. Das ist jedoch
falsch!

Maniascript würde die Ausführung des oberen Skripts mit einem Fehler abbrechen. Dieser tritt in der Funktion
spielerAnzahlUmEinsErhoehen auf: Hier wird die Variable
anzahlSpieler verwendet, die (sofern man nur diese eine Funktion betrachtet) noch nicht deklariert wurde! Ob sie an irgendeiner anderen Stelle im Code eventuell schon erstellt wurde (Wie es ja in
meineFunktion der Fall ist), ist unbedeutend.
Maniascript bietet für diese Fälle allerdings eine Möglichkeit, Variablen funktionenübergreifend zu deklarieren.
Variablen explizit verfügbar machen / declare for:
In Maniascript kann in Verbindung mit
declare das Schlüsselwort
for genutzt werden - Man spricht von einem "declare for" (Deutsch: Deklarieren für).
Mit diesem Hilfsmittel kann man eine Variable an eine "Elternvariable" knüpfen - An einer späteren Codestelle kann man anschließend über diese wieder auf die "Kindervariablen" zugreifen. So weit so gut, aber wie soll uns das bei funktionenübergreifenden Variablen nützen?
Ganz einfach: Wir knüpfen unsere zu deklarierende Variable an eine Variable, die einfach
überall verfügbar ist.

Solche Variablen nennt man "globale Variablen" - Maniascript bietet euch standardmäßig folgende globale Variablen an:
| Name | Datentyp | Beschreibung |
| CurrentLocalDateText | Text |  | Achtung: Existiert nicht mehr oder wurde umbenannt |
Beispiel: 2011/08/15 15:28:32 |
| CurrentTimeText | Text |  | Achtung: Existiert nicht mehr oder wurde umbenannt |
Beispiel: 4:02:18.69 |
| CurrentTime | Integer | Die Anzahl der Sekunden, die seit dem Starten von ManiaPlanet vergangen sind. |
| MouseLeftButton | Boolean | Entspricht True, wenn gerade die linke Maustaste gedrückt ist, ansonsten False. |
| MouseMiddleButton | Boolean | Entspricht True, wenn gerade die mittlere Maustaste gedrückt ist, ansonsten False. |
| MouseRightButton | Boolean | Entspricht True, wenn gerade die rechte Maustaste gedrückt ist, ansonsten False. |
| KeyUp | Boolean | Entspricht True, wenn gerade die obere Pfeiltaste gedrückt ist, ansonsten False. |
| KeyRight | Boolean | Entspricht True, wenn gerade die rechte Pfeiltaste gedrückt ist, ansonsten False. |
| KeyDown | Boolean | Entspricht True, wenn gerade die untere Pfeiltaste gedrückt ist, ansonsten False. |
| KeyLeft | Boolean | Entspricht True, wenn gerade die linke Pfeiltaste gedrückt ist, ansonsten False. |
| KeyReturn | Boolean | Entspricht True, wenn gerade die Entertaste gedrückt ist, ansonsten False. |
| KeySpace | Boolean | Entspricht True, wenn gerade die Leertaste gedrückt ist, ansonsten False. |
 | Hinweis: Diese Variablen könnt ihr an jeder beliebigen Stelle eures Codes nutzen, ohne sie vorher zu deklarieren oder verfügbar zu machen. |
 | Hinweis: Abhängig von der Anwendung des Skriptes (Manialink, EditorPlugin, ...) existieren noch andere globale Variablen - Diese sind im jeweiligen Kapitel unter "Anwendungen" aufgelistet.  |
Nun können wir unsere Variable, die in anderen Funktionen verfügbar sein soll (Oben:
anzahlSpieler), an eine beliebige dieser globalen Variablen anknüpfen. Dies geschieht bei der normalen Deklarierung dieser Variable (
declare), indem man ein
for und dem Namen der neuen Elternvariable anhängt:
declare Integer anzahlSpieler for CurrentTime = 0;
Diese Änderung alleine reicht aber nicht - Maniascript würde beim oberen Beispiel wieder mit einem Fehler abbrechen, da die Variable
anzahlSpieler in der Funktion
spielerAnzahlUmEinsErhoehen immer noch nicht genau deklariert wurde. Doch wir sind schon ein großes Stück weiter:
Mit dieser ersten Änderung haben wir die Variable an eine globale Variable geknüpft, die auch in
spielerAnzahlUmEinsErhoehen verfügbar ist - Alles, was wir jetzt noch tun müssen, ist in dieser Funktion sich von der globalen Variable
anzahlSpieler wieder zurückzuholen.

Dies geschieht wiederum mit einem
declare for, nur dass wir bei dieser Deklaration keinen Wert für die Variable angeben - In diesem Fall wird Maniascript den bereits vorhandenen Wert der Variable so belassen:
declare Integer anzahlSpieler for CurrentTime;
 | Achtung: Ihr müsst hier selbstverständlich die gleiche globale Variable verwenden, an die ihr die Variable vorher auch angknüpft habt.  |
 | TODO: Abschnitt umschreiben, declare for funktioniert nur mit Objekten  |
Der komplette Code, in dem die Variable
anzahlSpieler funktionenübergreifend deklariert und verwendet wird sähe somit so aus:
Void spielerAnzahlUmEinsErhoehen(){
declare Integer anzahlSpieler for CurrentTime;
anzahlSpieler = anzahlSpieler + 1;
}
Void meineFunktion(){
declare Integer anzahlSpieler for CurrentTime = 0;
spielerAnzahlUmEinsErhoehen();
}
Nach Ausführung von
spielerAnzahlUmEinsErhoehen in
meineFunktion würde der Wert der Variable
anzahlSpieler natürlich um
1 gestiegen sein.

Anbei das selbe Schema noch einmal bildlich dargestellt:
Vordefinierte Funktionen
Maniaplanet bietet euch bereits ein paar vordefinierte Funktionen an - Diese könnt ihr problemlos überall in eurem Code verwenden.
| Name | Parameter | Rückgabe-Datentyp | Beschreibung |
| log | * wert | - | Oft will man sich während der Laufzeit bestimmte Werte ausgeben lassen, um zu überprüfen, ob alles wie gewollt läuft oder um eine Fehlerursache aufzuspüren. Hierzu bietet der Maniaplanet-Client einen eigenen Debugger an, der mit Strg + G geöffnet werden kann (Einmal drücken für die Minimalansicht (Nur das Ausgabefenster), zweimal für das vollständige Fenster).
Mithilfe der Funktion log (1 Parameter, kein Rückgabewert) könnt ihr Werte ins Ausgabefenster des Debuggers schreiben:
log(3);
log("Hallo");
Nach Ausführung dieses Codeschnipsels sollten in der Debugger-Ausgabe zwei neue Zeilen stehen – "3" und "Hallo". Die log-Funtion nimmt alle Datentypen als Parameter entgegen, wandelt diesen in einen Text um und gibt ihn aus. |
| assert | Boolean wert | - | Die Funktion assert besitzt ebenso wie log einen Parameter und keinen Rückgabewert. Dieser muss vom Typ Boolean sein. Entspricht der übergebene Wert True, geschieht nichts – Ist er allerdings False, so wird das gesamte Skript gestoppt, als wäre ein Fehler aufgetreten.
Dies ist vor allem hilfreich, wenn es darum geht, keinen falschen Code ausführen zu lassen – So kann z.B. mit ein paar Aufrufen der assert-Funktion sichergestellt werden, dass keine falschen Werte in Berechnungen aufgenommen werden.
Der folgende Code würde dementsprechend nichts tun:
assert(True);
assert(4 == 4);
Einer der unteren Codes würde allerdings die Ausführung des gesamten Skriptes abbrechen:
assert(5 == 9);
declare Boolean meinZustand = False;
assert(meinZustand); |
| substring | Text text, Integer anfang, Integer laenge | Text teilText |  | TODO: Mittlerweile in der TextLib verfügbar - Beschreibung muss noch angepasst werden. |
Mithilfe der Funktion substring lässt sich ein bestimmter Teil eines Textes extrahieren. Der zurückgegebene Teil beginnt an der Zeichenstelle anfang des übergebenen Textes text an und ist laenge Zeichen lang.
Beispiele:
declare Text spielerName = "destroflyer";
//Würde "destro" zurückliefern
declare Text spielerNameAnfang = substring(spielerName, 0, 6);
//Würde "flyer" zurückliefern
declare Text spielerNameEnde = substring(spielerName, 6, 5);
//Würde "rofl" zurückliefern 
declare Text aufDemBodenRollendLachend = substring(spielerName, 4, 4); |
Arrays, Lists:
Um dieses Thema nicht zu kompliziert zu beginnen (

), werde ich zuerst eine kleine Einführung darin geben, was ein Array überhaupt ist und wofür es sich nutzen lässt:
Oft benötigt man in seinem Programm eine Liste an Werten – Wenn ihr z.B. die Namen aller eurer Strecken in eurem Skript verwenden möchtet, müsstet ihr ja für jeden Namen eine eigene Variable erstellen. Für diesen Fall bieten Programmiersprachen im Normalfall das Hilfsmittel des Arrays an: Ein Array ist eine feste Sammlung an Werten.
In Maniascript basieren Arrays auf dem Key-Value-Prinzip (Fachbegriff: Assoziative Arrays), d.h. jeder Wert im Array (Man spricht von den einzelnen Elementen) besitzt einen individuellen (!) Schlüssel, über den der restliche Code auf dieses Element zugreifen kann.
Der Schüssel und der Wert können jeden beliebigen Datentyp haben (Unabhängig voneinander, jedoch müssen alle Schlüssel untereinander und alle Elemente untereinander denselben Datentyp besitzen!), im Normalfall verwendet man allerdings ganze Zahlen (
Integer), die die Reihenfolge der Elemente im Array darstellen – Das erste Element besitzt den Schlüssel
0 (Der Computer beginnt immer bei
0 an, zu zählen – Ihr könntet natürlich auch bei
1 anfangen, ich würde es euch aber nicht empfehlen, da die
0 als Key des ersten Elements einfach der Standard ist

), das zweite Element den Schlüssel
1, das dritte den Schlüssel
2, und so weiter.
In vielen Situationen bietet es sich aber auch an, andere Datentypen als Schlüssel zu verwenden, z.B.
Texte. Außerdem kann der Schlüssel ebenso wie der Wert eine Bedeutung haben – Inwiefern ihr das Key-Value-Prinzip nutzt, ist euch überlassen – Man kann sich aber auf jeden Fall eine Menge Arbeit sparen, wenn man mit Arrays umgehen kann.
Wie kann ich Arrays in Maniascript nutzen?
Da es sich bei einem Array letztlich auch nur um eine Variable mit einem speziellen Datentyp handelt, müssen wir lediglich die Deklaration des Variablen-Typs ein klein wenig ändern: Statt des simplen Datentyps wie z.B. "
Integer" oder "
Boolean" deklariert man einen Array-Typ, indem man zuerst den Datentyp der Elemente schreibt und dahinter in eckigen Klammern
[...] den Datentyp der Schlüssel. Ein Array, dessen Werte
Texte und dessen Schlüssel
Integers sind, erstellt man also folgendermaßen:
declare Text[Integer] meinArray;
Dieses Array wäre momentan aber selbstverständlich noch leer (Keine Elemente) – Wenn man ihm direkt die benötigten Elemente zuweisen will, kann man dies in folgender Schreibweise tun:
[Key1=>Value1, Key2=>Value2, Key3=>Value3, ...]
Es wird also immer zuerst ein Key, dann ein
=> und schließlich der zugehörige Wert genannt. Diese einzelnen Key-Value-Paare sind durch Kommata
, voneinander getrennt sind. Diesen Teil, mitsamt der eckigen Klammen, könnt ihr als Wert verwenden und mithilfe des
=-Operators der Variable zuweisen.
Beispiel: Ich möchte gerne ein Array, dessen Keys vom Typ
Integer sind und das
Booleans als Werte besitzt. In diesem Array sollen folgende Elemente (Key-Value-Paare) enthalten sein:
- Key: 2, Value: True
- Key: 5, Value: False
- Key: 42, Value: True
Das gewünschte Array würde man in Maniascript so formulieren:
declare Boolean[Integer] meinArray = [2=>True, 5=>False, 42=>True];
Array-Zugriff:
Nun haben wir zwar ein Array erstellt, können aber noch nicht damit umgehen.

Das erste, was wir dazu lernen müssen, ist das Abfragen einzelner Werte des Arrays. Wie bereits erwähnt, greift man über den (eindeutigen!) Schlüssel auf die entsprechenden Werte zu. Hierzu nennt man ganz normal die Array-Variable und schreibt hinter ihr in eckigen Klammern
[...] den Schlüssel des gewünschten Elements. Maniascript erstellt daraus anschließend den gewünschten Wert.

Würde ich also gerne das Element mit dem Schlüssel
42 aus meinem vorher erstellten Array geliefert bekommen, könnte ich dieses folgendermaßen abfragen:
declare Boolean gewuenschtesElement = meinArray[42];
Hierbei muss man natürlich immer besonders auf die Datentypen der Elemente im Array achten.

Auf dieselbe Weise lassen sich auch neue Werte in das Array eintragen bzw. bereits vorhandene überschreiben – Alles, was wir dazu tun müssen, ist dem entsprechenden Arrayeintrag (Mithilfe der eckigen Klammern deklariert) mithilfe des
=-Operators einen neuen Wert zuzuweisen:
meinArray[10] = False;
Existiert bereits ein Wert für den Schlüssel, der in den eckigen Klammern angegeben wurde, wird dieser mit dem neuen überschrieben – Falls noch kein Element mit diesem Schlüssel vorhanden ist, wird ein neues Key-Value-Paar innerhalb des Arrays erstellt.
 | Hinweis: Es würde nichts am Array ändern, den Wert abzufragen, in einer Variable zu speichern (Siehe Beispiel weiter oben) und dieser Variable anschließend einen neuen Wert zuzuweisen. Man würde somit nur diese Variable bearbeiten - Die "Verbindung" zum Array besteht nur, wenn dies explizit mit dem Array-Variablennamen und den eckigen Klammern deklariert wird! |
Die Array-Länge / count:
In vielen Situationen benötigt man die Länge (Anzahl der Elemente) eines Arrays - Wenn ich z.B. in einem Array die Logins aller aktuellen Spieler auf meinem Server speichere, kann ich mithilfe durch Länge dieses Arrays die aktuelle Spielerzahl auslesen, ohne dass ich mich darum in einer extra Variable kümmern muss.

Hierfür bietet Arrays die Variable
count an (siehe Kapitel: Variablen von Objekten), die immer die aktuelle Länge des zugehörigen Arrays enthält - Sie kann ausgelesen werden, indem man hinter den Arraynamen einen Punkt
. und den Variablennamen
count schreibt:
declare Text[Integer] spielerLogins = [0=>”destroflyer”, 1=>"xbody", 2=>"hylis"];
declare Integer anzahlSpieler = spielerLogins.count;
Der obere Code würde somit bewirken, dass die Variable
anzahlSpieler den Wert
3 enthält (Denn das Array
spielerLogins beeinhaltet drei Elemente).
Array-Methoden
Ein Array besitzt in Maniascript auch eigene Methoden (Innere Funktionen) - Diese werden wie innere Variablen durch den Arraynamen gefolgt von einem Punkt
. und dem Funktionsnamen (Evtentuelle Parameter wie gewohnt in runden Klammern
(...)) aufgerufen.
Anbei eine Tabelle der Methoden, die sich auf jedes Array anwenden lassen:
| Name | Parameter | Rückgabe-Datentyp | Beschreibung | Code-Beispiel |
| exists | * wert | Boolean | Liefert True zurück, falls im Array ein Element-Wert mit dem Wert des Parameters wert exisiert. Ansonsten False. | declare Boolean existiertSpielerDestroflyer = spielerArray.exists("destroflyer"); |
| existskey | * schluessel | Boolean | Liefert True zurück, falls im Array ein Element-Schlüssel mit dem Wert des Parameters schluessel exisiert. Ansonsten False. | declare Boolean existiertVierterSpieler = spielerArray.existskey(3); |
| remove | * wert | Boolean | Entfernt das Element, das den gleichen Wert wie der Parameter wert besitzt. Liefert zurück, ob der Vorgang erfolgreich (True) war oder nicht (False). | declare Boolean spielerEntfernenErfolgreich = spielerArray.remove("hylis"); |
| removekey | * schluessel | Boolean | Entfernt das Element, dessen Schlüssel den gleichen Wert wie der Parameter schluessel besitzt. Liefert zurück, ob der Vorgang erfolgreich (True) war oder nicht (False). | declare Boolean erstenSpielerEntfernenErfolgreich = spielerArray.remove(0); |
| add | * wert | - | Dem Array wird ein neues Element mit dem Wert des Parameters wert hinzugefügt. | spielerArray.add("xbody"); |
| sort | - | Array | Eine sortierte Kopie des Arrays wird zurückgegeben (Das betroffene Array selber wird nicht verändert!).
 | Hinweis: Hierbei wird das Array wird nach den Werten sortiert. |
| declare Text[Integer] sortierteSpielerArray = spielerArray.sort(); |
| keyof | * wert | * / Array | Liefert den Schlüssel eines Elementes mit dem gleichen Wert wie der Parameter wert. Falls kein solches Element existiert, wird ein Array zurückgegeben. | declare Integer schluesselVonDestroflyer = spielerArray.keyof("destroflyer"); |
 | Hinweis: Ein Array ist, obwohl es Variablen und Methoden besitzen kann, kein Objekt! (Siehe Kapitel: Klassen, Objekte) |
Kontrollstrukturen:
Mit den bereits gelernten Techniken könnt ihr jedoch nur Programme erstellen, die unabhängig von Variablen immer das gleiche tun bzw. die gleichen Befehle nacheinander ausführen. In eigentlich allen Programmiersprachen, darunter auch Maniascript, gibt es aber auch Wege, um das Programm unterschiedliche Wege gehen zu lassen.

Damit ist z.B. eine Abzweigung gemeint - Je nach dem, wie ein bestimmter Wert aussieht, soll das Programm einen anderen Codeabschnitt ausführen.
Mittels sogenannter "Kontrollstrukturen" kann man auf diese Weise den Programmablauf beeinflussen – Nicht nur Verzweigungen sind möglich, auch beispielsweise Schleifen, in denen Code mehrmals ausgeführt wird, sind erstellbar. Geschickt ineinander verschachtelt lassen sich mit ihnen viele Probleme geschickt lösen.

Eine Kontrollstruktur besitzt in der Regel einen "inneren Codeblock", der abhängig von der Kontrollstruktur z.B. einmal, mehrmals oder auch gar nicht ausgeführt wird (Es gibt noch weitere Möglichkeiten

). Er wird wie bei Funktionen in geschwungenen Klammern
{...} hinter den Namen der Kontrollstruktur deklariert:
Kontrollstruktur{
//Innerer Code
}
Ebenso können auch Kontrollstrukturen Parameter besitzen, und je nach Wert anders reagieren. Diese werden wie bei Funktionen in runden Klammern
(...) angegeben:
Kontrollstruktur(parameter1, parameter2, …){
//Innerer Code
}
Weitere allgemeine Details möchte ich an diesem Punkt noch nicht erwähnen, sondern bei den jeweiligen Kontrollstrukturen erklären. Ich denke, so ist es einfacher zu verstehen als alle Zusammenhänge auf abstrakter (~ allgemeiner) Ebene zu nennen.
If
Mit der Kontrollstruktur
if könnt ihr die bereits genannten "Verzweigungen" des Codes bewirken.

Ein
if besitzt einen Parameter und ist mit einer Abfrage vergleichbar: Der Parameter vom Typ
Boolean wird betrachtet und je nach dem, ob er
True oder
False entspricht, wird der innere Code des
ifs ausgeführt oder nicht:
if(boolscherWert){
//Innerer Code des if
//(Wird bei (boolscherWert == True) ausgeführt
}
if ist eine der meistgenutzten Kontrollstrukturen, die Anzahl der Einsatzmöglichkeiten ist nahezu unendlich:
//Ist das Spielermaximum erreicht?
if(anzahlSpieler > spielerMaximum){
//Spieler wieder vom Server werfen?

}
//Handelt es sich beim Spieler um destroflyer
if(spielerLogin == "destroflyer"){
//Dem User 1000 Planets überweisen

}
Else
else ist nicht das Gegenteil von
if, sondern vielmehr eine Ergänzung (
else kann nur in Verbindung mit einem
if genutzt werden!). Diese Kontrollstruktur besitzt keine Parameter, sondern nur einen inneren Codeblock. Deklariert man direkt hinter einem
if ein
else, so wird dessen Code ausgeführt, falls die Abfrage des vorigen
ifs fehlschlägt:
if(boolscherWert){
//Innerer Code des if
//(Wird bei (boolscherWert == True) ausgeführt
}
else{
//Innerer Code des else
//(Wird bei (boolscherWert == False) ausgeführt
}
Mit einem
else könnt ihr nun die mehrmals angesprochene Verzweigung erstellen:
//Vorheriger Code
if(spielerLogin == "destroflyer"){
log("destroflyer ist da.");
}
else{
log("Jemand, der nicht destroflyer ist, ist da");
}
//Nachfolgender Code
Im oberen Codebeispiel führt das Programm immer zuerst den "vorherigen Code" aus, bis es auf das
if trifft – Nun geht es je nach dem, ob die Variable
spielerLogin den Wert
"destroflyer" enthält oder nicht, entweder den Weg über den Code des
ifs oder den des
elses, bis der Programmfluss schließlich wieder beim "nachfolgenden Code" zusammenläuft.
While
Ein
while stellt in Programmiersprachen wie Maniascript eine klassische Schleife dar.

Ebenso wie bei der Kontrollstruktur
if wird hier ein bool’scher Ausdruck als Parameter verlangt – Der innere Code wird anschließend so lange ausgeführt wie der Wert des Parameters
True ist: (Man sollte darauf achten, dass dies irgendwann nicht mehr der Fall ist - Sonst würd das Programm endlos weiterlaufen

)
declare Integer anzahlSpieler = 10;
while(anzahlSpieler > 0){
anzahlSpieler = anzahlSpieler – 1;
}
Würde man den oberen Code ausführen, würde der innere Code des
whiles genau zehn Mal ausgeführt werden – Die Variable
anzahlSpieler (Startwert:
10) wird bei jedem Durchlauf um
1 verringert, was zwangsläufig dazu führt, dass sie einen negativen Wert bekommt (
10 ->
9 ->
8 -> ... ->
2 ->
1 ->
0 ->
-1). Somit ergibt der bool’sche Ausdruck, der als Parameter für das
while benutzt wird, ab diesem Punkt
False und die Schleife wird abgebrochen.

Lest euch den oberen Abschnitt noch einmal genau durch, falls ihr etwas nicht verstanden habt, denn Schleifen sind essentiell für größere Programme – Fast immer, wenn ihr große Datenmengen (Stichwort: Arrays) besitzt, seid ihr darauf angewiesen, dass euer Programm automatisch die vielen Schritte erledigt.
Mit einem
while kann man jedoch auch gezielt eine Endlosschleife (Schleife, die niemals unterbrochen wird) erzeugen. Dazu kann man einfach als Parameter den Wert
True übergeben, der ja bekanntlich niemals
False ergeben kann:
while(True){
//Endlosschleife
}
For
for ist lediglich eine leicht abgewandelte Version des
whiles – Hier gebt ihr nicht an, wie lange der Code ausgeführt wird, sondern wie oft.

Hierfür verlangt for drei Parameter: Eine Variable (Auch Schleifenvariable genannt, meist wird hier die Variable
i genutzt) und zwei
Integers, den Start- und den Endwert.
Das Ganze funktioniert anschließend so:
1.) Maniascript weißt der von euch angegebenen Variable den übergebenen Startwert zu
2.) Nun wird überprüft, ob die Schleifenvariable bereits einen höhere Wert als den Endwert enthält
2.1.) Ja - Schleife abbrechen
2.2.) Nein - Inneren Code ausführen, den Wert der Schleifenvariable um
1 erhöhen und wieder zurück zu Schritt 2.)
Mit anderen Worten: Die Differenz ((Endwert+1) – Startwert) entspricht der Anzahl, wie oft der innere Code ausgeführt werden soll. Vorteil hierbei ist, dass ihr innerhalb des fors natürlich die Schleifenvariable abfragen und verarbeiten könnt:
for(i, 0, 10){
log(i);
}
Der obere Code würde euch zehnZeilen in der DebuggerKonsole ausgeben – Zuerst "0”, dann "1”, dann "2”, und so weiter bis "10”.
 | Hinweis: Für (Schleifenvariable = EndWert) wird der innere Code nicht ausgeführt, da bei dieser Konstellation die Schleife in Schritt 2.) abgebrochen wird  |
Selbstverständlich könnt ihr auch während der Schleife den Wert der Schleifenvariable ändern – Maniascript wird euren Code immer nach dem oberen Schema ausführen – Achtung: Wenn ihr die Schleifenvariable innerhalb der Schleife modifiziert, achtet darauf, keine (ungewollten) Endlosschleifen zu erzeugen.
Maniascript bietet dem Programmierer auch die Wahl, das Schleifenintervall selbst feszulegen - Hierbei handelt es sich um die Zahl, die nach jedem Durchlauf auf die Schleifenvariable addiert wird, standardmäßig
1. Hierzu gibt man einfach einen vierten Parameter (Datentyp:
Integer) an:
//Schleifenintervall = 2
for(i, 0, 10, 2){
log(i);
}
Somit würde hier nur jede zweite Zahl ausgegeben werden, da die Schleifenvariable immer um
2 hochgezählt wird, bis sie einen größeren Wert als
10 enthält.
Foreach
Die
foreach-Kontrollstruktur ist wie
while und
for eine Schleifenart – Jedoch ist sie speziell auf Arrays zugeschnitten. Wie bereits erwähnt, spielen Arrays bei großen Datenmengen eine Rolle – Und hierzu gehören selbstverständlich auch passende Schleifen wie
foreach, die durch das komplette Array iterieren. Dieser Begriff (iterieren) wird euch in diesem Tutorial noch häufiger begegnen - Er bedeutet so viel wie "durch das Array laufen und jeweils Element für Element betrachten".

Die
foreach-Schleife iteriert nun also durch das Array, speichert ein Element in einer Variable ab und führt den inneren Code aus (Der auf diese Variable natürlich zugreifen kann

) - Dies wird einmal für jedes Element im Array durchgeführt. (In chronologischer Reihenfolge (Reihenfolge, in der die Elemente eingefügt wurden))
Die Syntax der Parameter für die
foreach-Schleife weicht ein wenig vom Standard ab: Die Kontrollstruktur benötigt 2 Parameter: Das Array und die Variable, in der das jeweilige Element gespeichert wird. Deklariert wird diese Kontrollstruktur wie folgt:
foreach(aktuellesElement in meinArray){
//Innerer Code
}
Wie ihr seht, schreibt man in die runden Klammern
(...) zuerst den Namen der Variable für das zu aktuelle Element, gefolgt von einem
in und dem Namen des Arrays.
Beispiel: Nehmen wir an, wir hätten ein Array, in dem wir die Logins von ein paar Spielern gespeichert haben – Zum Beispiel so:
declare Text[Integer] spielerLogins = [0=>”destroflyer”, 1=>"xbody", 2=>"hylis"];
Nun wollen wir alle diese Logins auf der DebuggerKonsole ausgeben lassen – Die Lösung ist wie immer denkbar einfach: Wir iterieren mithilfe einer
foreach-Schleife durch das Array und geben im inneren Code der Kontrollstruktur das jeweilige Element (Hier: Der jeweilige Login) aus:
declare Text[Integer] spielerLogins = [0=>”destroflyer”, 1=>"xbody", 2=>"hylis"];
foreach(aktuellerLogin in spielerLogins){
log(aktuellerLogin);
}
Nach Ausführung würdet ihr drei neue Zeilen in der Debugger-Ausgabe sehen: "destroflyer", "xbody" und "hylis".
foreach unterstützt aber auch das Abfragen der Schlüssel und nicht nur der Werte – Wollt ihr in eurem inneren Code auch den Schlüssel des aktuellen Elements verfügbar haben, deklariert ihr die Schleife einfach folgendermaßen:
foreach(aktuellerSchluessel => aktuellesElement in meinArray){
//Innerer Code
}
Ihr fügt also lediglich den Namen der Variable, in dem der jeweils aktuelle Schlüssel gespeichert werden soll und ein
=> vorne in die runden Klammern
(...) ein.

Um beim oberen Beispiel mit den Spieler-Logins zu bleiben - Wir könnten hiermit nun auch den entsprechenden Schlüssel des Login-Elements im Array ausgeben lassen:
declare Text[Integer] spielerLogins = [0=>”destroflyer”, 1=>"xbody", 2=>"hylis"];
foreach(aktuellerSchluessel => aktuellerLogin in spielerLogins){
log(aktuellerSchluessel ^ ": " ^ aktuellerLogin);
}
Somit würden wir folgende drei Zeilen im Debugger loggen: "0: destroflyer", "1: xbody", "2: hylis".
Switch
Ein
switch ist im Gegensatz zu den vorigen Kontrollstrukturen relativ speziell – Im Grund besteht er aus einer Reihe von Abfragen, die euch bei einer Fallunterscheidung helfen können.

Hier wird nur ein Parameter verlangt: Der Ausdruck (z.B. eine Variable oder ein Vergleich), der untersucht werden soll.
Maniascript vergleicht anschließend den Wert dieses Ausdrucks mit einer Reihe von angegebenen Möglichkeiten. Welche Möglichkeiten es allerdings gibt und wie das Programm auf sie reagieren soll, bestimmt ihr selbstverständlich. (Die Kontrollstruktur übernimmt lediglich die Arbeit der vielen Vergleiche)
Man spricht hier bei den erwähnten Möglichkeiten von den sogenannten "Fällen" (Deutsch: Fall, Englisch: case). Im inneren Code definiert ihr folgendermaßen alle Fälle, die ihr benötigt und welcher Code bei welchem Fall ausgeführt werden soll:
switch(anzahlSpieler){
case 0:{
//Programmcode Nr.1
}
case 27:{
//Programmcode Nr.2
}
case 42:{
//Programmcode Nr.3
}
}
Wie ihr vielleicht bereits erahnen könnt, gebt ihr die verschiedenen Fälle mit
case an, gefolgt von dem möglichen Fall und einem Doppelpunkt
:. Der anschließende Codeblock (Innererhalb der geschwungenen Klammern
{...}) wird ausgeführt, sofern der zu untersuchende Ausdruck denselben Wert wie der deklarierte Fall besitzt.
Würde die Variable
anzahlSpieler also den Wert
0 besitzen, würde "Programmcode Nr.1" ausgeführt werden. Hätte sie dagegen den Wert
27, würde Maniascript den "Programmcode Nr.2" ausführen und so weiter...
Diese Kontrollstruktur ist besonders hilfreich, wenn eine Vielzahl an Möglichkeiten für eine Variable existieren und auf jeden dieser möglichen Fälle anders reagiert werden muss.
Für den Fall, dass der aktuelle Wert des übergebenen Ausdrucks nicht von euch deklariert wurde, passiert bei der Ausführung des
switches nichts. Falls ihr aber wollt, dass in einem solchen Fall (Der ja vielleicht beabsichtigt ist) ein "Standard-Code" ausgeführt wird, könnt ihr folgendes schreiben:
switch(anzahlSpieler){
case 0:{
//Programmcode Nr.1
}
case 42:{
//Programmcode Nr.2
}
default:{
//Programmcode Nr.3
}
}
Deklariert wird ein solcher "Standardfall" mit dem Schlüsselwort
default (Englisch: default, Deutsch: Standard)). Würde der Wert der Variable
anzahlSpieler also weder
0 noch
42 sein, würde immer der "Programmcode Nr.3" ausgeführt werden.
 | Achtung: Bei einem switch muss mindestens 1 möglicher Fall deklariert sein - Andernfalls liefert der Compiler einen Fehler. |
Direktiven
Direktiven bezeichnen in Maniascript spezielle Zeilen am Anfang eines Skriptes. Eine Direktive startet immer mit einer Doppelkreuz
# und ist einzeilig. Es existieren folgende Direktiven:
| Direktive | Beschreibung |
| #RequiredContext benoetigterKontext | Der benötigte Kontext des Skriptes. Dieser kann angegeben werden, um zu verhindern, dass das Skript an der falschen Stelle ausgeführt wird, z.B ein EditorPlugin als GameMode |
| #Const name wert | Deklariert eine Konstante namens name, deren Wert wert entspricht. Der Wert einer Konstanten kann während des Skriptes nicht verändert werden. |
| #Setting parameter wert | Aus Sicht des Skriptes, besitzt #Setting dieselbe Wirkung wie #Const - Eine Konstante namens parameter mit dem Wert wert wird angelegt.
Werte, die allerdings mit #Setting angegeben wurden, können von außerhalb des Skriptes verändert bzw. eingegeben werden. (Englisch: Setting, Deutsch: Option) |
| #Include "scriptName" as name | Lädt die Programmbibliothek oder Datei namens scriptName und bindet ihre Funktionen an den Namensraum name. |
 | Hinweis: Diese Zeilen stellen keine noramlen Programmbefehle dar und benötigen dementsprechend kein Semikolon ; am Ende der Zeile. |
 | TODO: Codebeispiele für die verschiedenen Direktiven |
Skripte anhalten:
Maniascript bietet euch mithilfe des Schlüsselwort
yield einen Befehl, der das Programm für die kleinstmögliche Zeiteinheit anhält und die Anzeige, z.B. den Manialink, aktualisiert: (In dieser Zeit könnt ihr auf keine Events oder ähnliches reagieren!)
yield; //Das Skript hält kurz an und aktualisiert die Anzeige
Auf den ersten Blick mag die kleine "Pause" wenig Sinn haben, doch wenn ihr diesen Befehl mit ein paar geschickten Kontrollstrukturen kombiniert, könnt ihr nette Effekte erzielen.

Auf diese Weise bietet uns Maniascript bereits zwei vordefinierte Funktionen, die auf dem
yield-Befehl basieren (Oder zumindest mit diesem erklärt werden können

).
sleep
Die
sleep-Funktion (Kein Rückgabewert) besitzt einen Parameter vom Typ
Integer - Dieser stellt die Anzahl Millisekunden dar, die das Skript anhalten soll. Folgender Aufruf würde die Ausführung des Programms somit genau eine Sekunde lang anhalten:
sleep(1000);
Laut Nadeo lässt sich der genaue Ablauf im Inneren der Funktion
sleep so erklären:
Void sleep(Integer dauerInMillisekunden){
Start = Now;
while(Now < Start + dauerInMillisekunden){
yield;
}
}
Wie ihr seht, hält diese Funktion das Skript so lange immer ein kleines Stückchen an (per
yield), bis die übergebene Zahl an Millisekunden vergangen ist.
wait
Mithilfe von
wait könnt ihr euer Skript so lange stoppen, bis eine bestimmte Bedingung erfüllt ist, also ein von euch übergebener bool'scher Ausdruck
True ergibt. Dieser bool'sche Ausdruck ist der einzige Parameter der
wait-Funktion, die ebenso wie
sleep keinen Wert zurückliefert.
Als kleines Beispiel nehme ich eine Eingabefläche für den User - Wir haben bereits eine Funktion
sindAlleTextfelderAusgefuellt (ohne Parameter) geschrieben, die einen
Boolean zurückliefert. Dieser sagt aus, ob der User alle Textfelder ausgefüllt hat (Wie genau das funktioniert, interessiert uns an diesem Punkt gar nicht).
Nun wollen wir, dass das Skript direkt nach der letzten Eingabe des Users weiter ausgeführt wird, ohne dass erst ein Button oder ähnliches gedrückt werden muss.

Die Lösung ist relativ simpel: Wir benutzen die
wait-Funktion und übergeben ihr als Parameter die Funktion
sindAlleTextfelderAusgefuellt.
Maniascript wird anschließend das aktuelle Programm solange unterbrechen, bis die Funktion
sindAlleTextfelderAusgefuellt den Wert
True zurückliefert.
//Manialink ist geladen
wait(sindAlleTextfelderAusgefuellt());
//Eingaben auswerten
 | Hinweis: wait berechnet natürliches ebenso wie die Kontrollstrukturen while oder for den übergebenen bool'schen Ausdruck jedes Mal neu. Beachtet daher, dass Funktionen, die in euren Ausdrücken vorkommen, evtl. sehr oft aufgerufen werden! |
Auch für
wait bietet Nadeo eine offizielle Erklärung mithilfe des
yield-Befehls:
while(!boolscherAusdruck){
yield;
}
Klassen, Objekte:
Oft werden die eigenen Programme so komplex, dass man bestimmte Zusammenhänge und Werte nicht mehr in einfachen Variablen speichern kann. Nehmen wir beispielsweise eine Userliste: Das Programm soll eine Liste der aktuell eingeloggten User, ihren Profilbildern und ihrer Email-Adresse anzeigen – Wer fleißig den vorigen Teil des Tutorials gelesen hat, dem fällt bestimmt sofort das Stichwort "Array" ein.

Klar, denn wir könnten die User in einem Array speichern... Doch wenn wir genauer nachdenken, fällt uns auf, dass wir pro User aber drei Einträge (Login, Profilbild, Email) und nicht nur einen benötigen. Wir könnten zwar ein paar Arrays verschachteln, aber das würde das Problem bei der nächsten Änderung des Codes nur noch verschlimmern. Die Lösung für solche Situationen, in denen mehrere Variablen zu einem einzigen Objekt zusammengefasst werden sollen, heißt "Objektorientierte Programmierung" (OOP):
Das Grundkonzept der objektorientierten Programmierung besteht darin, Klassen zu definieren. Eine Klasse stellt einen "komplexen" Objekttyp dar – Es könnte also z.B. eine
Auto-, eine
Server- oder eine
User-Klasse geben. Nachdem wir eine solche Klasse definiert haben, können wir problemlos Variablen dieses Typs erstellen, beispielsweise eine User-Variable (So könnten wir im oberen Beispiel unser Array mit Objekten unserer
User-Klasse befüllen).
Wir erschaffen auf diese Weise anders gesagt eigene Variablentypen. Der Vorteil hierbei ist, dass wir die Eigenschaften unserer Klassen selber festlegen – Wir definieren (!) also bei der
Auto-Klasse im wahrsten Sinne des Wortes, was für das Programm ein "Auto" sein soll.

Dies geschieht, indem wir der Klasse beliebig viele Variablen zuweisen können, wir könnten also sagen: Ein Objekt der Klasse
Auto besteht aus:
- Name (Text)
- Höchstgeschwindigkeit (Integer)
- Hersteller (Text)
Wenn wir jetzt später im Code eine Variable vom Typ
Auto erstellen, besitzt diese automatisch in ihrem Inneren diese drei Variablen
Name,
Höchstgeschwindigkeit und
Hersteller, auf die wir nun zugreifen können.

Überall, wo Variablen zusammengehören, kann man also Klassen definieren, um sich selber das Handling zu erleichtern und andererseits, um die Zusammenhänge zwischen den einzelnen Werten genau festzulegen. Besonders bei größeren Programmen ist es sehr wichtig, objektorientierte Programmierung richtig einzusetzen, da man sich sonst in einem langgezogenen Code wiederfindet, der alle möglichen Variablen erst einzeln abfragen muss, diese auf irgendeine noch kompliziertere Weise verarbeitet und am Ende versucht, das ganze relativ normal aus- bzw. zurückzugeben – Informatiker sprechen hierbei vom sogenannten "Spaghetti-Code".
Deklarieren einer Klasse:
Momentan bietet Maniascript noch keine Möglichkeit, eigene Klassen zu erstellen - Die bereits vorhandenen (vordefinierten) Klassen können jedoch problemlos genutzt werden.
Zugriff auf Objekte:
Mithilfe eines Punktes
. könnt ihr auf Eigenschaften (Variablen) und Methoden (Funktionen) eines Objektes zugreifen - Dazu schreibt ihr ihn hinter den Namen des Objektes, gefolgt vom Aufruf der gewünschten Variable bzw. Funktion:
meinObjekt.anzahlSpieler = 11;
meinObjekt.spielerAnzeigeFunktion();