Benutzer-Werkzeuge

Webseiten-Werkzeuge


scripting:tutorials:level2:lua_library

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

scripting:tutorials:level2:lua_library [2025/07/15 14:26] – angelegt fritz_98scripting:tutorials:level2:lua_library [2025/07/18 14:38] (aktuell) fritz_98
Zeile 1: Zeile 1:
-Zu besprechen:+======Die Lua-Standardbibliothek======
  
-pairsipairs (kennt man schon)+In Ebene 2 unseres Skript-Tutorials dreht sich vieles darumneue Funktionen kennenzulernen. Dadurch werden die Möglichkeiten, Lua-Variablen oder das Spiel selbst zu beeinflussen, deutlich ausgebaut. An dieser Stelle ist es wichtig, dass du die [[scripting:tutorials#grundlagen_lua-programmierung|Grundlagen]] unbedingt kennst und verstanden hast.
  
-next+In diesem Artikel geht es darum, einige wichtige Funktionen aus der Lua-Standardbibliothek vorzustellen. Lua bietet dem Programmierer standardmäßig nicht nur [[scripting:tutorials:level1:variables|Datentypen]] und [[scripting:tutorials:level1:branches|Kontrollfluss]], sondern auch "Standardfunktionen", die sehr oft gebraucht werden und darum nicht jedes mal vom Nutzer selbst programmiert werden sollten. Eine davon ist ''table.getn'', die du bereits [[scripting:tutorials:level1:tables#nutzung_von_schleifen|im Artikel zu Tables]] kennengelernt hast. Aber auch mathematische Funktionen, wie die Berechnung der [[scripting:reference:standard_library:math:sqrt|Quadratwurzel]] oder des [[scripting:reference:standard_library:math:sin|Sinus]] einer Zahl zählen dazu.
  
-unpack+Es wäre nicht sinnvoll, jede einzelne der Funktionen hier aufzulisten. Diese Liste findest du (nach Kategorie sortiert) [[scripting:reference:standard_library|hier]]. Da aber nicht jeder die komplette Referenz studiert, existiert dieser Artikel, um zumindest auf die wichtigsten Standardfunktionen, auf die man immer wieder stößt, aufmerksam zu machen.
  
-math.random+Es lohnt sich, die einzelnen Funktionen einmal auszuprobieren, um zu schauen, was sie tun. Kaputtmachen kann man damit glücklicherweise nichts - die wirklich "gefährlichen" Funktionen stehen in Siedler nicht zur Verfügung.
  
-table.getn+----
  
-table.insert/table.remove+====pairs und ipairs==== 
 + 
 +[[ scripting:reference:standard_library:base:pairs |pairs]] und [[ scripting:reference:standard_library:base:ipairs |ipairs]] geben sogenannte //Iteratoren// zurück, die für [[scripting:tutorials:level1:loops#for-schleife|for-Schleifen]] benutzt werden können. Die [[scripting:tutorials:level3:iterators|Konstruktion von Iteratoren]] wird erst in Ebene 3 beschrieben, aber die von Lua bereitgestellten sollte man kennen. Wie sie verwendet werden, erklärt direkt der [[scripting:tutorials:level2:loops|nächste Artikel]]. 
 + 
 +\\ 
 + 
 +====next==== 
 + 
 +[[ scripting:reference:standard_library:base:next |next (_Table [, _Key ])]] gibt für ein Table ''_Table'' das nächste [[scripting:tutorials:level1:tables#tables_als_woerterbuecher|Key-Value-Paar]] des Tables, abhängig von ''_Key'' zurück. Der "nächste" Wert ist dabei nicht notwendigerweise der, der der Reihenfolge entspricht, in der man das Table befüllt hat, sondern bezieht sich darauf, wie das Table intern gespeichert ist. Man hat darum keinen Einfluss darauf, in welcher Reihenfolge man via ''next'' Werte zurückerhalt. 
 + 
 +Ist ''_Key'' nicht angegeben (daher die eckigen Klammern - der Parameter ist optional), wird ein beliebiges Key-Value-Paar zurückgegeben (falls vorhanden). Ist ''_Table'' leer oder das letzte Element erreicht, wird **nil** zurückgegeben. 
 + 
 +Meistens wird die Funktion dazu benutzt, um zu prüfen, ob ein Table leer ist: 
 +<code lua> 
 +function IsTableEmpty(_Table) 
 +    return next(_Table) == nil 
 +end 
 +</code> 
 +Da die Funktion mehrere Rückgabewerte hat, hilft beim Verständnis sicher auch der [[scripting:tutorials:level2:functions#mehrere_rueckgabewerte|zugehörige Artikel]]. 
 + 
 +\\ 
 + 
 +====unpack==== 
 + 
 +[[ scripting:reference:standard_library:base:unpack |unpack (_Table)]] gibt für ein **[[ scripting:tutorials:level1:tables#tables_als_listen |numerisches Table]]** ''_Table'' alle Werte (einzeln) zurück. Wie Funktionen mit mehreren Rückgabewerten verwendet werden, erfährst du im [[scripting:tutorials:level2:functions#mehrere_rueckgabewerte|zugehörigen Artikel]]. Stell dir dazu folgendes vor: In einem Table können zwar mehrere Werte gespeichert sein (z.B. ''{0, 42, 5, "Dario"}''), aber das Table selbst ist eine **einzige** Variable. Mit ''unpack'' kannst du aus dem Table wieder einzelne Variablen machen: 
 +<code lua> 
 +-- Wir zeigen zwei Varianten, um das Beispieltable zu entpacken 
 +-- Variante 1 mit den bereits bekannten Mitteln: 
 + 
 +-- Beginne mit dem Table 
 +MyTable = {0, 42, 5, "Dario"
 +-- Speichere nun alle Werte in einzelne Variablen 
 +Variable1 = MyTable[1] 
 +Variable2 = MyTable[2] 
 +Variable3 = MyTable[3] 
 +Variable4 = MyTable[4] 
 + 
 +-- Variante 2 unter Zuhilfenahme von unpack: 
 + 
 +-- Beginne wieder mit dem Table 
 +MyTable = {0, 42, 5, "Dario"
 +-- Speichere nun alle Werte in einzelne Variablen mit unpack 
 +Variable1, Variable2, Variable3, Variable4 = unpack(MyTable) 
 +</code> 
 +Beide gezeigten Varianten haben genau den gleichen Effekt. Der Vorteil von ''unpack'' ist, dass man die Größe des Tables nicht kennen muss und vor allem bei großen Tables deutlich weniger zu schreiben hat. 
 + 
 +\\ 
 + 
 +====math.random==== 
 + 
 +[[scripting:reference:standard_library:math:random|math.random(_a, _b)]] ermittelt eine (ganzzahlige) Zufallszahl. In welchen Grenzen sich diese Zufallszahl bewegt, hängt von den Parametern ''_a'' und ''_b'', bzw. ob sie überhaupt angegeben wurden. 
 + 
 +Sind ''_a'' und ''_b'' angegeben, wird eine ganze Zahl zwischen (einschließlich) ''_a'' und ''_b'' zurückgegeben. Ist nur ''_a'' angegeben, wird eine ganze Zahl zwischen ''1'' und ''_a'' zurückgegeben. Sind keine Parameter angegeben, wird eine [[https://de.wikipedia.org/wiki/Rationale_Zahl|rationale Zahl]] zwischen 0 und 1 zurückgegeben. 
 + 
 +Falls man eine rationale Zufallszahl mit einer größeren Obergrenze als 1 braucht, kann man das Ergebnis von ''math.random'' einfach mit dieser Obergrenze multiplizieren: 
 +<code lua> 
 +-- Ermittle eine Zufallszahl zwischen 0 und 2*π 
 +RandomNumber = math.random() * 2*math.pi 
 +</code> 
 + 
 +\\ 
 + 
 +====table.getn==== 
 + 
 +[[ scripting:reference:standard_library:table:getn |table.getn (_Table)]] hast du schon in Ebene 1 kennengelernt. Die Funktion gibt die Anzahl der sequentiellen numerischen Einträge im Table ''_Table'' zurück (also wie viele Einträge von Index ''1'' aufwärts ununterbrochen im Table sind). 
 + 
 +Die Funktion wird oft in Schleifen verwendet, um durch numerische Tables zu iterieren (siehe z.B. [[scripting:tutorials:level1:tables#nutzung_von_schleifen|hier]]). In Kombination mit [[scripting:reference:standard_library:math:random|math.random(_a, _b)]] kann sie auch verwendet werden, um ein zufälliges Element aus einem numerischen Table zu wählen: 
 +<code lua> 
 +MyTable = {"Hallo", "Hello", "Salut", "Ciao", "Hola", "Hej"
 + 
 +-- Wähle zufällig einen Gruß: 
 +RandomIndex = math.random(table.getn(MyTable)) 
 +RandomGreeting = MyTable[RandomIndex] 
 + 
 +print(RandomGreeting) 
 +</code> 
 + 
 +\\ 
 + 
 +====table.insert/table.remove==== 
 + 
 +[[ scripting:reference:standard_library:table:insert |table.insert (_Table, [_Index,] _Value)]] und [[ scripting:reference:standard_library:table:remove |table.remove (_Table, [_Index,] )]] fügen einen **[[ scripting:tutorials:level1:tables#tables_als_listen |numerischen]]** Eintrag in das Table ''_Table'' am Index ''_Index'' ein oder löschen ihn wieder heraus. Für alle anderen Einträge (bzw. solche mit höherem Index) werden die jeweiligen Indizes angepasst, sodass das nicht händisch gemacht werden muss. Ein kleines Beispiel, in dem wir einen Eintrag einfügen und einen anderen löschen: 
 +<code lua> 
 +-- hier stimmt etwas nicht 
 +MyOrder = {1, 1, 2, 9, 5, 8, 13} 
 +-- wir entfernen die Zahl an Stelle 5 
 +table.remove(MyOrder, 4) 
 + 
 +-- table.getn gibt nun die richtige Länge des Tables zurück, 
 +-- nämlich 6 (da wir ein Element entfernt haben) 
 +for i = 1, table.getn(MyOrder) do 
 +    -- Index 1 bis 6 sind lückenlos besetzt, da table.remove den Index der letzten drei Werte 
 +    -- (also 5, 8 und 13) um jeweils 1 reduziert hat 
 +    print(i .. ": " .. MyOrder[i]) 
 +end 
 + 
 +-- jetzt setzen wir an die Stelle 4 die korrekte Zahl 
 +-- An Stelle 4 steht eigentlich schon eine Zahl (nämlich 5) 
 +-- Die rückt automatisch zusammen mit allen folgenden Zahlen um 1 nach oben 
 +table.insert(MyOrder, 4, 3) 
 + 
 +-- table.getn passt sich auch bei einem table.insert-Aufruf an 
 +for i = 1, table.getn(MyOrder) do 
 +    -- Index 1 bis 7 sind lückenlos besetzt, da table.insert den Index der letzten drei Werte 
 +    -- (also 5, 8 und 13) um jeweils 1 erhöht hat 
 +    -- Der Index 4 wurde nicht überschrieben 
 +    print(i .. ": " .. MyOrder[i]) 
 +end 
 +</code> 
 + 
 +\\ 
 + 
 +====(Fast) alles, was mit Mathe zu tun hat==== 
 + 
 +Leider mögen einige Leute Mathematik nicht besonders. Fürs Programmieren ist sie aber unerlässlich. Die [[scripting:reference:standard_library:math|Übersicht über die math-Funktionen]] solltest du gut durchlesen, um deine Möglichkeiten zur Befolgung (einfacher) Rechenvorschirften zu kennen. Die [[scripting:tutorials:level1:variables#zahlen|Grundrechenarten]] reichen oft nicht aus. 
 + 
 +Ein Beispiel ist die Funktion ''LookAt(_Settler, _Entity)'', die eine Entity ''_Settler'' so ausrichtet, das sie ''_Entity'' anschaut. Sie funktioniert allerdings **nur** für Siedler (im ersten Parameter). Willst du beispielsweise ein Gebäude auf eine Straße ausrichten oder eine Palisade senkrecht zu einem Bezugspunkt, hilft [[scripting:reference:standard_library:math:atan2|math.atan2]]. 
 + 
 +Auch kann es vonnöten sein, den Abstand zwischen zwei (Entity-)Positionen zu ermitteln. Dazu braucht man den [[https://de.wikipedia.org/wiki/Satz_des_Pythagoras|Satz des Pythagoras]], mit dessen Hilfe der [[https://de.wikipedia.org/wiki/Euklidischer_Abstand|Euklidische Abstand]] in der (Siedler-)Ebene ausgerechnet wird. Ohne [[scripting:reference:standard_library:math:pow|Potenz]] und [[scripting:reference:standard_library:math:sqrt|Quadratwurzel]] ist das nicht möglich. 
 + 
 +---- 
 + 
 +Im nächsten Kapitel beschäftigen wir uns mit fortgeschrittenen Schleifen und lernen unter anderem die oben kurz beschriebenen Funktionen ''pairs'' und ''ipairs'' näher kennen. 
 + 
 +[[ scripting:tutorials:level2:loops | Nächstes Kapitel: Weiteres zu Schleifen ]]\\ 
 +[[ scripting:tutorials:level2:lua_library| Zurück nach oben ]]
scripting/tutorials/level2/lua_library.txt · Zuletzt geändert: 2025/07/18 14:38 von fritz_98