LSL Scripting Teil 2 - Hello World 
Tutorials
Sonntag, den 14. September 2008 um 11:41 Uhr

Willkommen bei Teil 2 der LSL Scripting Tutorial Reihe, der Skriptsprache Second Lifes, mit der man relativ komplexe Vorgänge programmieren und ausführen kann.

Im LSL Scripting Teil 1 haben wir die Grundlagen erlernt. Wir haben gesehen, dass ein Script eine bestimmte Struktur haben muss und wir haben die wichtigsten Teile dieser Struktur aufgezeigt und erklärt.

Heute möchte ich Euch ein wenig tiefer in die Materie einführen. Wie jedes Buch oder Tutorial, welches vom Scripting oder Programmieren handelt, beginnt man ein bestimmtes Beispiel umzusetzen. Dies will ich hier natürlich auch machen.


Wir beginnen mit einem einfachen "Hello World" Beispiel, um nochmal die Struktur zu vertiefen.
default
{
        state_entry()
        {
                llSay(0, "Hello World!");
         }
}
Dies ist das simpelste Beispiel eines "Hello World" Scripts. Auch hier sehen wir wieder die im ersten Teil angesprochene Grundstruktur. Ganz aussen herum den globalen Container, den state "default", darin dann das event "state_entry()" und darin die Function "llSay()". Wenn wir dieses Script so speichern und dann in ein Objekt in Second Life einfügen, so bekommen wir im public chat den Text: 
[00:00] Object: Hello World!
Dieser Text wird sofort ausgegeben, sobald wir das Script in das Objekt einfügen und wir haben nur eine Möglichkeit, diesen Text nochmal zu bekommen, nämlich indem wir das Script resetten.
Das event "state_entry()" wird nur einmal ausgeführt, wenn das Script gestartet wird und sonst nicht mehr. Ein weiteres Beispiel ist die Ausgabe des gleichen Textes, aber auf Klick mit der Maus auf das Objekt:
default
{
        touch_start(integer total_number)
        {
                llSay(0, "Hello World!");
         }
}
Der aufmerksame Leser sieht sofort den Unterschied:
Statt des events "state_entry()", benutzen wir jetzt das event "touch_start()". Dieses event reagiert nur auf einen Klick mit der Maus des Users auf das Objekt, das das Script enthält. Das event "state_entry()" ist nicht zwingend notwendig, es wird aber empfohlen, es immer mit aufzunehmen, der Verständlichkeit wegen:
default
{
        state_entry()
        {}
        touch_start(integer total_number)
        {
                llSay(0, "Hello World!");
         }
}
Hier habe ich also das event "state_entry()" wieder mit aufgenommen, aber es tut nichts. Es ist vollkommen leer. Legen wir dieses Script so wie es ist in ein Objekt, passiert erstmal gar nichts.
Wir müssen auf das Objekt klicken, um ihm den Text zu entlocken. Tun wir das und wir erhalten exakt denselben Text wie oben. Es gibt noch viele andere Möglichkeiten die Ausgabe des Textes zu provozieren. Eine ist recht interessant:
default
{
        state_entry()
        {}
        collision_start(integer num_detected)
        {
                llSay(0, "Hello World!");
         }
}
Das event "collision_start()" reagiert auf, wie der Name schon sagt, Kollision mit dem User. Wenn wir dieses Script in ein Objekt einfügen, passiert erstmal wieder gar nichts.
Wir müssen mit unserem Avatar gegen das Objekt laufen und es berühren, damit der gleiche Text wie oben ausgegeben wird.
Dieses event werden wir gleich mal nutzen, um etwas Sinnvolleres zu scripten.
Als nächstes lernen wir mit Variablen umzugehen. Beginnen wir einfach einmal, das letzte Beispiel etwas umzubauen:
integer status = 0;
default
{
        state_entry()
        {}
        collision_start(integer num_detected)
        {
                llSay(0, "Hello World!");
         }
}
Wir fügen ganz oben, ausserhalb des states "default" eine weitere Zeile ein. Hier definieren wir eine Variable "status", weisen ihr den Typ "integer" (Ganzzahl) zu und übergeben ihr auch schon einen Wert, nämlich 0. Diese Variable ist nun eine "globale Variable", das heisst dass diese Variable im gesamten Script, egal in welchem state (man kann mehrere states haben, dazu später mehr), oder in welchem event man sie benutzen möchte, gültig ist und zur Verfügung steht. Man kann Variablen auch in einem event definieren, dann hat die Variable auch nur in diesem event Gültigkeit. Man nennt sie dann eine "lokale Variable". In einem anderen event ist diese Variable dann nicht bekannt und kann nicht genutzt werden. In unserem Fall brauchen wir aber eine globale Variable, weil wir einen Status definieren müssen, der über mehrere events benutzt werden soll.
Als Nächstes lernen wir eine neue Funktion kennen. Sie dient dazu Bedingungen zu überprüfen und anhand des Ergebnisses dann unterschiedliche Aktionen aufzurufen. Solch eine "if-Bedingung" dürfte fast jedem bekannt sein:
integer status = 0
default
{
        state_entry()
        {}
        collision_start(integer num_detected)
        {
                 if (status == 0)
                {
                        status = 1;
                }
                else
                {
                        status = 0;
                }
        }
}
Was tun wir hier? Nun, sobald das Script gestartet wird, also in ein Objekt eingefügt wird, oder das Objekt in dem sich das Script befindet, gerezzt wird, hat die Variable status den Wert 0. Läuft nun jemand gegen das Objekt, löst also jemand eine Kollision aus, so bekommt die Variable den Wert 1, weil sie zuvor den Wert 0 hatte (if (status == 0)). Läuft dann wieder jemand gegen das Objekt, bekommt die Variable wieder den Wert 0. Es ist also ein Status, der bei Kollision geändert wird.
So, was nun?
Es gibt ein paar sehr nützliche Zeit-Funktionen in LSL. Eine davon werden wir nun nutzen um die Zeit zwischen den beiden Kollisionen zu messen. Dazu brauchen wir zwei globale Variablen welche die Anfangs- und die Endzeit speichern sollen:
integer status = 0
integer start;
integer stopp;
 
default
{
        state_entry()
        {}
        collision_start(integer num_detected)
        {
                if (status == 0)
                {
                        status = 1;
                        start = llGetUnixTime();
                }
                else
                {
                        status = 0;
                        stopp = llGetUnixTime();
                }
        }
}
Wie ihr seht, haben wir nun direkt im Kopf des Scripts zwei neue Variablen definiert, die dort noch ohne Inhalt sind, also leer definiert werden. Wenn nun jemand zum ersten Mal mit dem Objekt kollidiert, so sorgt die neue Funktion "llGetUnixTime()" dafür, das der aktuelle UNIX-Timestamp, also die Anzahl an Sekunden seit dem 01.01.1970, in die Variable "start" eingefügt wird.
Rennt dann nochmal jemand gegen das Objekt, erhält die Variable "stopp" ebenfalls den aktuellsten Unix-Timestamp. Dies können wir nun ganz simpel nutzen, um uns die Zeit zwischen der ersten und der zweiten Kollision ausgeben zu lassen:
integer status = 0
integer start;
integer stopp;
 
default
{
        state_entry()
        {}
        collision_start(integer num_detected)
        {
                if (status == 0)
                {
                        status = 1;
                        start = llGetUnixTime();
                        llSay(0, "Stoppuhr gestartet!");

                }
                else
                {
                        status = 0;
                        stopp = llGetUnixTime();
                        integer timediff = stopp - start;
                        llSay(0, "Zeit: "+(string)timediff+" Sekunden.");
                }
        }
}

Hier haben wir jetzt nochmal eine lokale Variable eingefügt und übergeben ihr gleich bei der Definierung auch den entsprechenden Wert, nämlich das Ergebnis von (stopp - start).

Damit bekommen wir die Anzahl der Sekunden, die zwischen den beiden Kollisionen vergangen sind.

Dies ist also eine kleine, nunja ziemlich ungenaue Stoppuhr, weil sie nur sekundenweise zählt. Natürlich kann man das auch deutlich genauer machen. Das soll aber hier jetzt nicht zu weit führen.

Im nächsten Teil lernen wir etwas über events, die vorher durch eine Funktion initialisiert werden müssen, wie zum Beispiel das timer-event. Ausserdem werden wir unsere Stoppuhr etwas besser konfigurieren.

Ich hoffe, die Tutorials helfen euch weiter. Forumuliert gern eure Fragen als Kommentar.


Artikelserie weiterlesen

SL Scripting Teil 3 - Alles über Events

frühere Artikel der Serie:

LSL Scripting Teil 1 - Die Grundlagen


 

Bitte Einloggen oder Registrieren um Kommentare zu schreiben.

Panorama 

Neue Artikel:
rss-005

Metaversen 

Neue Artikel:
VWI RSS

IT / Tech 

Neue Artikel:
VWI RSS

Second Life 

Neue Artikel:
rss-005

Mitmach-News 

Neue Artikel:
rss-005