Voraussetzung: "Der Einstieg in lua“
Es gibt so manche Aufgaben, die einem ziemlich oft bei der Programmierung begegnen, bzw. man denkt "Diesen Teil
müsste man doch abkürzen" können.
So ist z.B die Ausgabe eines Textes mit oder ohne Bild eine recht komplexe Sache wenn man die
MessageBox
direkt in lua schreiben möchte.
Vorallem wenn nach dem Klick auf
OK
noch eine weitere Aktion folgen soll.
Auch das Ersetzen von Variablen in Strings (z.B. bei der
Übersetzung
deines Cartridges in verschiedene Sprachen
ist eine Sache, die man nicht bei jedem neuen Wherigo neu schreiben möchte.
Abbildung 1: Einbinden des globales Codes
Zu diesem Zwecke habe ich mir angewöhnt eine
global.lua
Datei anzulegen, die ich im überordneten Ordner
aller Wherigo liegen habe und die von jedem WIG-Projekt genutzt werden kann.
Ein Beispiel:
- Im Ordner
C:\Wherigos
liegt die Datei global.lua
- Im Ordner
C:\Wherigo\MeinTestWherigo
liegt dann die Projektdatei test.urwigo
- Im Ordner
C:\Wherigo\MeinZweiterWherigo
liegt dann entsprechend zweiterWIG.urwigo
Beide Cartridges, sowohl
test.urwigo
als auch
zweiterWIG.urwigo
verwenden
global.lua
aus dem übergeordneten Ordner
Abbildung 2: Auszug aus _cartridge.lua (enthalten im gwz Archiv)
Beim "Bauen" des cartrigdes bzw. beim Erstellen des
gwz
Archives spielt der Pfad dann keine Rolle mehr,
da der Inhalt der externen lua-Datei in die
_cartridge.lua
hineinkopiert wird
Abbildung 3: Boolean als Text oder Zahl
Nun aber zu den Methoden an sich. Den Anfang machen die Boolean Werte. Dabei ist es mir für debug Zwecke oft
hilfreich, wenn der Wert als Zahl oder String zurückgegeben wird, da eine Konkatenation in lua mit verschiedenen
Datentypen Probleme bereitet.
"Raetsel 1 geloest: " .. myBoolVar
führt zu einem Laufzeitfehler da hier string und boolean nicht
miteinander verknüpft werden kann.
"Raetsel 1 geloest: " .. bts(myBoolVar)
hingegen funktioniert, da nun zwei Strings verknüpft
werden. Die Ausgabe lautet dann
"Raetsel 1 geloest: true"
Dass getBoolAsString als bts (boolToString) abgekürzt ist bzw. dass es mal
value
und mal
condition
heißt ist historisch gewachsen. Kein guter Stil, wie ich zugeben muss, aber eine Methode umbenennen wird im
nachhinein schwierig, da man auch alle Aufrufe der Methode in zahlreichen Wherigo-Projekten anpassen muss.
Also lieber gleich sinnvolle Namen verwenden.
Die dritte Methode wählt zufällig
true
bzw.
false
, abhängig von einer
Wahrscheinlichkeit.
Bsp: Bei meinem
Fußball-Wherigo Heimspiel soll die
gegnerische Mannschaft nur in einem von drei Fällen ein Tor schießen.
getRandomBool(33)
löst diese Aufgabe.
math.random(100)
liefert eine Ganzzahl zwischen
1 und 100, also 5, 41, 87 ...
Ist diese Zahl kleiner als unsere Vorgabe
33
wird true zurück geliefert, ansonsten false.
Korrekterweise müsste es kleiner gleich heißen, da nicht von 0 bis 99 sondern von 1 bis 100 gezählt wird.
Abbildung 4: Ausgaben vereinfachen
Im zweiten Block geht es um die Ausgabe in Form von MessageBoxen. Da die ersten drei Methoden nur
Convenience-Wrapper für die vierte sind, beginnen wir auch bei letzerer in Zeile 38.
Hier wird eine MessageBox aufgebaut, die mit dem übergebenen Text
m
und einem optionalen Bildchen
med
gefüllt wird.
Als Callback wird der Teil bezeichnet, der ausgeführt werden soll, wenn der Spieler auf
OK
gedrückt
hat.
Hier wird es jetzt spannend. Lua unterstützt nämlich hier das Konstrukt einer "closure". D.h. es wird eine
Methode
cf
definiert (Zeile 35), die erst dann ausgeführt wird, wenn der MessageBox danach zumute ist.
Woraus besteht aber die Methode
cf
? Zunächst hat sie einen Parameter
action
. Ist
dieser Parameter null, so geschieht ... rein gar nix. Ich konnte diesen Fall noch nie beobachten. Wahrscheinlich ein Sicherheitscheck, falls man die MessageBox nicht mit "OK", sondern mit dem Back-Button des Smartphones verlässt.
Ruft hingegen die MessageBox die Methode
cf(anAction)
mit einem Not-Null-Parameter auf, so wird die
zweite innere Methode
fun
(wieder eine closure) ausgeführt.
Was aber ist denn
fun
?
fun
wird von außen definiert, z.B. in Zeile 29, wo der Befehl
"Zeige Mainscreen" übergeben wird. Auch hier gilt, in Zeile 29 wird
Wherigo.ShowScreen(Wherigo.MAINSCREEN)
nur definiert, aber noch nicht ausgeführt. Dies passiert erst,
wenn der Spieler in der MessageBox (z.B. "Gehe nun zum Final") auf "OK" drückt.
Achtung: Vergesst nicht bei der Definition der Methode die Schlüsselwörter
function()
und
end
. Ansonsten habt ihr keine closure definiert, sondern es wird direkt der Mainscreen angezeigt!
Jetzt wird sich der gewiefte Leser/Entwickler denken "Wozu brauche ich den
action
Parameter?".
Dieser dient theoretisch dazu weitere Informationen an die aufrufende Methode zu übergeben. Man könnte ne Zahl oder
einen String reinschreiben. Trotz längerer Studie des von Urwigo kompilierten Codes konnte ich aber stets nur den
action ~= nil
Vergleich finden.
Man kann allerdings einer MessageBox mehrere Buttons geben und damit einen Quasi-Input generieren. Über
action
(enthält "Button1" bzw. "Button2") kann man dann unterscheiden welcher Button gedrückt wurde.
Ein sinnvolles Szenario wäre "Du bist an der Zone Goldbergwerk angekommen. Die bereits abgebauten Goldklumpen wandern hiermit in dein Inventar", Button1 = "OK", Button2 = "Nachricht zukünftig nicht mehr anzeigen"
Abbildung 5: Debug-Ausgaben, Wegpunkt-Mittelung und String-Operationen
Nun aber genug der komplexen closure-Theorie. Zum Abschluss etwas leichtere Kost.
calcCenterZonePoint
liefert euch die GPS-Koordinate, die genau zwischen
point1
und
point2
liegt. Ist ganz praktisch um die Hälfte der Laufstrecke oder den Mittelpunkt eines Fußballfeldes zu bestimmen.
printTable
gibt beim debuggen den Wert einer Tabelle aus. Da jedes "Objekt" in lua als Tabelle definiert ist, kann das schon mal ganz hilfreich sein.
Die Werte einer Zone (Name, Koors, ob aktiv oder nicht...) sind ebenfalls als Tabelle gespeichert und können über
getmetatable()
abgerufen werden.
Als Ergebnis seht ihr beim Debuggen alle Infos über eure Zone.
Zum Schluss noch ein Beispiel für Substitution. Hier wird in einem String "Gehe zur Zone #1# und warte", "Schmiede" der Wert "Gehe zur Zone Schmiede und warte" gebildet. Hilfreich bei Mehrsprachigkeit eures Wherigos.