Benutzer-Werkzeuge

Webseiten-Werkzeuge


scripting:tutorials:level2:functions

Dies ist eine alte Version des Dokuments!


Weiteres zu Funktionen

Für ein lauffähiges Skript ist der korrekte Umgang mit Funktionen essentiell. Einige Funktionen, die Siedler bereitstellt, gehen über die Vorstellung, die wir in Ebene 1 erstanden haben, hinaus. In diesem Kapitel werden deshalb einige nützliche Möglichkeiten zur Verwendung von Funktionen präsentiert und Beispiele anhand der Siedler-API gegeben.


Hinweis: Unsere Beispiele in diesem und den folgenden Kapiteln können besser nachvollzogen werden, wenn man die Programmzeilen nebenbei ausprobieren kann. Dazu kann man diese Webseite hier verwenden:

https://www.lua.org/demo.html


Verkürzte Funktionsaufrufe

Wenn Funktionen nur einen einzigen Parameter haben und dieser Parameter entweder ein String oder ein Table ist, kann man den Funktionsaufruf mit diesem einen Parameter verkürzen.

Beispielsweise übergibt man an die Funktion print in der Regel nur einen einzigen String-Parameter. In so einem Fall können die runden Klammern weggelassen werden. Folgende Funktionsaufrufe sind äquivalent:

-- Zeigt "Hallo Welt" an
print("Hallo Welt")
 
-- Zeigt auch "Hallo Welt" an
print"Hallo Welt"

Es handelt sich dabei nur um eine alternative Schreibweise, die Funktionalität bleibt die gleiche.

Das gleiche Prinzip funktioniert auch, wenn ein Table als einziger Parameter erwartet wird. Wir definieren eine Funktion, die eine Person etwas sagen lässt:

-- _WhoAndWhat ist ein Table, das eine Person und einen Text enthalten kann, aber nicht muss
-- Wenn eine Angabe fehlt, wird ein Standardwert gesetzt
function SaySomething(_WhoAndWhat)
    -- Wenn die Quelle der Aussage fehlt (also nil ist), wird "Ein Unbekannter" als Quelle angenommen
    -- nil wird von if wie false interpretiert
    if not _WhoAndWhat.Person then
        _WhoAndWhat.Person = "Ein Unbekannter"
    end
 
    -- Das gleiche Prinzip für den Text
    if not _WhoAndWhat.Text then
        _WhoAndWhat.Text = "Je kälter, desto draußen"
    end
 
    print(_WhoAndWhat.Person.." sagt: ".._WhoAndWhat.Text)
end

So eine Funktion kann auf verschiedene Arten aufgerufen werden:

-- Variante 1: Man definiert ein (lokales) Table im Voraus und gibt es an die Funktion weiter
local WhoAndWhat = {
    Person = "Konfuzius",
    Text = "Der Weg ist das Ziel"
}
SaySomething(WhoAndWhat)
 
-- Variante 2: Man erstellt das Table im Funktionsaufruf und benutzt die Standardschreibweise
SaySomething({Person = "Kerberos"})
 
-- Variante 3: Der verkürzte Funktionsaufruf, bei dem ebenfalls das Table beim Funktionsaufruf erstellt wird
-- In der verkürzten Variante können die Klammern weggelassen werden
SaySomething{Person = "Niemand", Text = "Nutella schmeckt ohne Butter besser"}
 
-- Die Funktion ist so formuliert, dass auch ein leeres Table übergeben werden kann
-- Der verkürzte Funktionsaufruf sähe damit so aus:
SaySomething{}

Beispiele im Siedler-Skripting

Wir haben in Ebene 1 bereits Funktionen kennengelernt, die entweder einen einzelnen String oder ein einzelnes Table als Parameter haben.

Beispielsweise haben wir im Artikel zu Sieg- und Niederlagebedingungen die Funktion IsDead benutzt, um zu prüfen, ob eine Entität noch lebt oder nicht. Folgende Schreibweisen sind demnach äquivalent:

-- Variante 1
if IsDead("Player2") then
    -- Reaktion auf Ereignis
end
 
-- Variante 2
if IsDead"Player2" then
    -- Reaktion auf Ereignis
end

Hinweis: Du wirst die verkürzte Schreibweise für Strings in Mapskripten sehr selten finden, da sie weder besonders nützlich noch hübsch anzusehen ist. Wir wollten sie der Vollständigkeit halber trotzdem zeigen.

Im Artikel zu Briefings haben wir die Funktion StartBriefing vorgestellt, mit der ein Briefing nach einer Beschreibung in einem Table gestartet werden kann. Da diese Funktion nur das Table als Parameter nimmt, kommt dafür die alternative Schreibweise infrage:

-- Im verlinkten Artikel haben wir uns der Übersicht zuliebe für Variante 1 entschieden
local Briefing = {
    {
        title = "Dario",
        text = "Dies ist ein sehr kurzes Briefing. Ich grüße meine Mama, meinen Papa und Falki.",
        position = GetPosition("Dario")
    }
}
StartBriefing(Briefing)
 
-- Die Variante mit verkürzter Schreibweise sähe so aus:
StartBriefing{
    {
        title = "Dario",
        text = "Dies ist ein sehr kurzes Briefing. Ich grüße meine Mama, meinen Papa und Falki.",
        position = GetPosition("Dario")
    }
}

Hinweis: Je größer ein Table wird, desto unübersichtlicher wird der verkürzte Aufruf, weil weniger schnell ersichtlich wird, auf welche Funktion sich gerade bezogen wird. Speziell bei Briefings nimmt dir das außerdem die Möglichkeit, einzelne Seiten als globale Variable abzuspeichern, um sie ResolveBriefing zu übergeben. Die verkürzte Schreibweise ist also nicht automatisch die beste!
Wir werden im Artikel zu NPCs die Funktion CreateNPC kennenlernen, die sich für die verkürzte Schreibweise sehr eignet.


Mehrere Rückgabewerte


Zu viele und zu wenige Parameter

Möglicherweise ist es dir schon passiert, dass du einer Funktion die Parameter in der falschen Reihenfolge oder zu viele oder zu wenige Parameter angegeben hast. Falls du mit anderen Programmiersprachen vertraut bist, würdest du erwarten, dass solche Fälle Fehlermeldungen nach sich ziehen. Lua allerdings wird das erlauben und auch teilweise ausnutzen. In diesem Abschnitt wollen wir beleuchten, was passiert, wenn die Anzahl an gegebenen Argumenten nicht der erwarteten entspricht.

Der einfachere Fall ist der mit zu vielen Argumenten. Wir definieren eine Funktion, die drei Zahlen addiert:

function SumOfThree(_A, _B, _C)
    return _A + _B + _C
end

Wenn diese Funktion mit zu vielen Argumenten aufgerufen wird

SumOfThree(3, 25, 14, 9, 11)

werden nur die ersten drei beachtet und addiert, der Rest verworfen. Die Funktion hat keine Möglichkeit, auf die Argumente zuzugreifen. Allerdings wird kein Fehler angezeigt! Darauf zu achten, einer Funktion nicht zu viele Argumente zu übergeben, wird dem Programmierer überlassen.

Der Nutzen, den man daraus ziehen kann, ist eingeschränkt. Im Artikel zur Lua-Standardbibliothek wird die Funktion unpack beschrieben, mit der ein numerisches Table (Liste) „ausgepackt“ wird. Die Funktion gibt jeden Eintrag im Table einzeln als Rückgabewert aus (siehe auch den Abschnitt oben über mehrere Rückgabewerte). unpack kann also dazu benutzt werden, die Inhalte eines numerischen Tables einzeln als Argumente zu übergeben. Mit der Funktion SumOfThree können so die ersten drei Zahlen in so einem Table addiert werden:

local Numbers = {3, 25, 14, 9, 11, 17, 36}
 
print(SumOfThree(unpack(Numbers)))

Dieser Use Case lässt sich aber auch anders (und deutlich besser lesbar) umsetzen und soll hier nur als Beispiel dienen.
Hinweis: In der Lua-Demo kann die Funktion unpack nicht benutzt werden und muss durch table.unpack ersetzt werden.


Beliebig viele Parameter

scripting/tutorials/level2/functions.1694251052.txt.gz · Zuletzt geändert: 2023/09/09 09:17 von fritz_98