Auf dieser Seite findest du Tipps und Tricks zu Ereignissen, Schleifen und Timing. Damit steuerst du genau, wann in deinem Spiel bestimmte Ereignisse oder Zustandsänderungen (über Werte und Bedingungen) passieren.
Los geht's.
Pause (statisch)
Am einfachsten steuerst du Zeit mit dem Aktionsteil „Pause“. Er sorgt dafür, dass die Aktionsteile danach erst laufen, wenn die Pause vorbei ist.
| Hinweis: Im Aktionsteil „Pause“ kannst du die Zeit in Millisekunden, Sekunden oder Minuten angeben. Nimm am besten Millisekunden, damit kannst du am genauesten arbeiten. |
Hier ein Beispiel für „Pause“ zusammen mit anderen Aktionsteilen:
1. if condition "cond_example" is true 2. pause for 500 milliseconds 3. change condition "cond_example" to false 4. end if
Pause (dynamisch)
Mit demselben Aktionsteil baust du auch dynamische Pausen. Das lässt dein Spiel lebendiger wirken und weniger wie eine hängende Schallplatte, die immer dasselbe wiederholt.
Dafür legst du einen Wert an und verknüpfst ihn mit dem Aktionsteil „Pause“. Die Zahl eines Werts lässt sich jederzeit über Aktionsteile oder Skripte ändern; hier bleiben wir der Einfachheit halber bei Aktionsteilen.
Angenommen, du hast irgendwo im Editor einen Wert namens „v_time“ angelegt. So sieht eine dynamische Pause in einem Aktionsblock aus:
1. set random value "v_time" between 1000 and 5000 2. pause for "v_time" milliseconds 3. play animation "anim_example" and wait 4. jump to action part #1
Ereignisse in Animationsframes
Wusstest du, dass du Animationsframes über
bearbeiten und jedem einzelnen Frame Sounds und Aktionen zuweisen kannst? Das ist eine sehr gute Methode für exakt getimte Ereignisse, weil sie an die Frames der Animation gebunden sind und nicht an die Bildrate, mit der dein Spiel auf dem Gerät des Spielers läuft. Das ist viel genauer als der Aktionsteil „Pause“.
Warten in Aktionen
Manche Aktionsteile haben eine zusätzliche Option „Warten“. Ist sie aktiviert, hält die Engine die Aktionsliste an, bis die Aktion oder Animation fertig ist. Diese Optionen sind freiwillig, helfen aber sehr, den Zeitpunkt von Ereignissen zu steuern.
Animation abspielen und warten
Startet eine Animation und hält die Aktionsliste an, bis die Animation fertig ist. Verwende das nicht bei Animationen in Endlosschleife, sonst bleibt die Aktionsliste für immer stehen, weil die Animation nie endet.
Warten, bis Animation beendet ist
Wie oben, nur für eine Animation, die bereits läuft. Auch hier gilt: nicht bei Animationen in Endlosschleife verwenden, sonst bleibt die Aktionsliste für immer stehen.
Warten, bis Sound beendet ist
Hält die Aktionsliste an, bis der verknüpfte Sound zu Ende ist. Wie bei „Animation abspielen und warten“ darfst du keinen Sound in Endlosschleife verknüpfen, sonst wartet die Aktionsliste ewig.
Warten, bis Bedingung sich geändert hat
Hält die Aktionsliste an, bis sich die Bedingung ändert oder einen bestimmten Zustand erreicht.
| Hinweis: Es gibt drei Möglichkeiten. |
| 1. Changed: warten, bis die Bedingung ihren Zustand wechselt. |
| 2. True: warten, bis die Bedingung den Zustand true hat. |
| 3. False: warten, bis die Bedingung den Zustand false hat. |
Warten, bis Wert sich geändert hat (statisch)
Hält die Aktionsliste an, bis der Wert das angegebene Ziel erreicht.
Warten, bis Wert sich geändert hat (dynamisch)
Hält die Aktionsliste an, bis der Wert denselben Stand hat wie ein zweiter verknüpfter Wert. Dynamisch ist das, weil sich beide Werte ändern lassen; den zweiten Wert kannst du so für viele Situationen wiederverwenden.
| Hinweis: Zum Vergleichen gibt es mehrere Operatoren, das gibt dir viel Spielraum. |
| = gleich. |
| != ungleich. |
| <= kleiner oder gleich. |
| < kleiner als. |
| >= größer oder gleich. |
| > größer als. |
Warten, bis Charakter aufhört zu sprechen
Hält die Aktionsliste an, bis der Charakter aufhört zu sprechen. Spricht er gar nicht, geht es sofort weiter.
Warten, bis Charakter stehen bleibt
Hält die Aktionsliste an, bis der Charakter stehen bleibt. Läuft er gar nicht, geht es sofort weiter.
Charakter zu Position/Objekt schicken und warten
Das sind eigentlich zwei Aktionsteile: Der eine schickt den Charakter zu einer Position in der aktuellen Szene, der andere zur Position eines Objekts. Beide haben eine Warten-Option und halten die Aktionsliste an, bis der Charakter angekommen ist.
| Hinweis: Die Engine wartet nicht wirklich auf das Ziel, sondern darauf, dass der Charakter stehen bleibt. Lege beide Aktionsteile deshalb am besten in eine Zwischensequenz, damit der Spieler den Weg nicht durch einen Klick woanders hin unterbrechen kann. |
Aktion aufrufen/beenden und warten
Mit diesem Aktionsteil rufst du einen anderen Aktionsblock auf. Optional wartet die aktuelle Aktionsliste, bis der aufgerufene Block alle seine Aktionsteile und Skripte abgearbeitet hat. Ob sich das über mehrere Aktionsblöcke verketten lässt, ist nicht getestet; probier es gern aus und gib in der Community Bescheid.
Schleifen
Jetzt wird es etwas komplizierter: Es geht um Skripte und um ein paar übliche und unübliche Wege mit Aktionsteilen und Animationen.
Animationen sind ebenfalls Schleifen
Richtig gelesen: Animationen sind auch Schleifen und lassen sich so nutzen. Du legst fest, wie oft eine Animation läuft, wie lang ein Durchlauf dauert und wie viele Frames sie hat. Hängst du Aktionen oder Code an bestimmte Frames, sagst du dem Spiel, dass es etwas x-mal tun soll, oder unbegrenzt, wenn die Animation endlos läuft. Wie du Frames bearbeitest und ihnen Aktionen oder Skripte gibst, steht unter Ereignisse in Animationsframes.
| Hinweis: Die Animation kann Bilder, ein einzelnes Bild, leere Frames oder Frames mit einer transparenten PNG- oder WebP-Datei enthalten. |
Zum Aktionsteil springen
Der Aktionsteil „Zu Aktionsteil springen“ ist ein Weg, Schleifen im Editor ganz ohne Skript zu bauen. Es gibt zwei Varianten:
Absolut
Diese Variante brauchst du am häufigsten, und sie ist die einfachste: Die Engine springt direkt zu Aktionsteil Nummer x im aktuellen Aktionsblock. Nummer 1 ist der erste Aktionsteil, also der oberste in der Liste.
Ein kurzes Beispiel für einen solchen Aktionsblock:
1. if condition "cond_example" is false 2. pause for 500 milliseconds 3. jump to action part #1 (jump back to first action part) 4. end if 5. display text "hello world" (if condition "cond_example" is true then this would be executed instead)
Relativ
Der relative Modus ist etwas kniffliger: Er springt x Schritte vor oder zurück und hängt stärker von der Situation ab.
Ein kleines Beispiel, wie das aussehen kann:
1. pause for 500 milliseconds 2. if condition "cond_example" is true 3. jump 4 action parts forwards (0) 4. else (1) 5. jump to action part #1 (2) 6. end if (3) 7. display text "hello world" (4)
Die setDelay()-Funktion
Mit der Funktion setDelay() steuerst du, wann Codezeilen oder Funktionen ausgeführt werden. Damit lassen sich auch zeitgesteuerte Schleifen bauen.
Syntax
setDelay(delay, function)
Vorhandene Funktion aufrufen
setDelay(1000, "helloworld()") -- call function helloworld() after 1000ms (1 second)
Eigene Funktion ausführen
setDelay(1000, function()
print("hello world!") -- print "hello world" to the log after 1000ms (1 second)
-- you can insert any code you like between function() & end
end)
Schleife mit Verzögerung
local i = 0 -- create variable i & set default value as 0
function example()
i = i + 1 -- increment i by 1
print(i) -- print the value of i to the log
setDelay(1000, "example()") -- call the example() function again after 1000ms (1 second)
end
example() -- call the example() function to start the loop
| Hinweis 1: Lege das setDelay() in der Schleifenfunktion am besten in eine if-Abfrage, damit du die Schleife beenden kannst, wenn sie nicht mehr gebraucht wird. |
| Hinweis 2: Damit baust du leicht eine Schleife mit fester Anzahl Durchläufe: Erhöhe oder verringere bei jedem Durchlauf einen Wert und rufe setDelay() nur auf, solange der Wert noch nicht x ist. Erreicht er x, endet die Schleife von selbst. |
mainLoop
Der Event-Handler mainLoop ist die bekannteste Art, in Skripten eine Schleife laufen zu lassen. Anders als die Schleife mit setDelay() läuft mainLoop ständig, solange er registriert ist. Wann dein Code darin tatsächlich ausgeführt wird, steuerst du mit if-Abfragen.
mainLoop ist einer der wenigen Event-Handler, für den sich mehrere Funktionen in einem Projekt registrieren lassen, und du kannst ihn wieder abmelden, wenn du ihn nicht mehr brauchst.
registerEventHandler()
registerEventHandler("mainLoop", "exampleLoop") -- register exampleLoop() as a looping function & start looping
unregisterEventHandler()
unregisterEventHandler("mainLoop", "exampleLoop") -- unregister exampleLoop as a looping function & kill the loop
Einfaches Beispiel
local i = 0 -- create variable i & set default value as 0
exampleLoop()
i = i + 1 -- increment i by 1
print(i) -- print the value of i to the log
end
registerEventHandler("mainLoop", "exampleLoop")
Beispiel mit Tickrate
local i = 0 -- create variable i & set default value as 0
exampleLoop()
i = i + 1 -- increment i by 1
if i == 10 then -- check if i equals 10
print("hello world!") -- print "hello world!" to the log
i = 0 -- reset i back to 0
end
end
Beispiel mit getTime()
local time = nil -- create variable time & set default value as nil
exampleLoop()
if time == nil then time = getTime({flags=1, reset=true}) else time = getTime() end -- init or update time
if time >= 3000 then -- if time more than or equals 3000ms then
print("hello world!") -- print "hello world!" to the log
time = getTime({flags=1, reset=true}) -- reset time back to 0ms
end
end
registerEventHandler("mainLoop", "exampleLoop")
| Hinweis: Tickrate und getTime() sind für Verzögerungen nicht sehr genau, weil mainLoop an die Systemschleife gebunden ist, die selten gleichmäßig läuft. Ein Durchlauf kann 4 ms dauern, der nächste 33 ms. Für Verzögerungen, die nicht ganz exakt sein müssen, reicht es aber. |
While
Eine while-Schleife führt ihren Inhalt aus, solange die Bedingung erfüllt ist. Ein kurzes Beispiel:
local i = 0 -- create variable i & set default value as 0
while(i <= 10) do -- while i is less than or equal to 10 do
print(i) -- print the value of i to the log
i = i + 1 -- increment the value of i by 1
end
| Hinweis: Visionaire Studio verträgt while-Schleifen schlecht. Solange sie läuft, kann das Spiel nicht weiterzeichnen, und je nach Einsatz kann es abstürzen. Vermeide sie möglichst und nutze sie nur mit Vorsicht. |
Repeat until
Eine repeat-until-Schleife führt ihren Inhalt aus, bis die Bedingung erfüllt ist. Ein kurzes Beispiel:
local i = 0 -- create variable i & set default value as 0
repeat -- init repeat loop
print(i) -- print the value of i to the log
i = i + 1 -- increment the value of i by 1
until(i > 10) -- kill loop when i is greater than 10
| Hinweis: Auch repeat-until-Schleifen verträgt Visionaire Studio schlecht. Solange sie läuft, kann das Spiel nicht weiterzeichnen, und je nach Einsatz kann es abstürzen. Vermeide sie möglichst und nutze sie nur mit Vorsicht. |
Zum Schluss
Sicher gibt es noch weitere Tricks für Timing und Schleifen, etwa mit Plugin-Aktionsteilen, der Skriptsprache Ilios oder dem visuellen Skripting. Für den Anfang reicht das hier aber. Hast du eigene Tipps, teile sie gern in der Community, damit diese Seite ergänzt werden kann.
Ressourcen
| Name | Beschreibung |
|---|---|
| N/A | Leider gibt es keine Beispieldatei (.ved) und keine Ressourcen zum Herunterladen. |
