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 überAnim editframev2.pngbearbeiten 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“.

Vs anim frame actions.png


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.