Voraussetzung: "Mit lua alle Zonen des Wherigos erfassen“
Als Oregon Nutzer aber auch als Wherigo-Programmierer ist man bestimmt schon des Öfteren über das Problem gestolpert, dass die Garmin-Hardware einfach nicht mehr auf Höhe der Zeit und somit viel zu langsam ist. Recht deutlich wird dies, wenn in einem WIG recht viele Zonen gleichzeitig aktiv sein sollen. Im Geoclub liest man von maximal sieben Zonen, die das Oregon gerade noch so vertragen soll. Meine 300er Version funktionierte zwar auch noch mit 9 gleichzeitig aktiven Zonen, doch die Reaktionsfähigkeit inkrementierte in den Minutenbereich. Auf deutsch: Will man ne Zone, eine Person auswählen oder einfach nur den Bildschirmtext mit "OK" bestätigen muss man darauf gefasst sein, dass das Gerät erst nach 30 bis 60 Sekunden reagiert. Von Spielvergnügen ist da schon lange keine Rede mehr und die Gefahr eines Absturtzes steigt ebenso an. Es muss also Abhilfe her. Die einfache Lösung lautet daher: Nie so viele Zonen gleichzeitig aktiv schalten.
Das ist natürlich meistens nicht so einfach möglich. Besonders bei dynamischen Spielen, wo der User selbst entscheiden kann, wo er hingehen möchte scheint dies erstmal unmöglich. Was aber möglich ist, dass nur die nächsten n (z.B 5) Zonen angezeigt werden. Die Idee dabei ist, dass man die Zonen nach Entfernung zum Spieler sortiert und die ersten n Zonen angezeigt werden. Ein Timer kann alle paar Sekunden überprüfen, welche Zonen am Nähesten liegen und entsprechend den Active-Status umsetzen. Einfach gesprochen, doch wie wird es umgesetzt.
Als Voraussetzung muss man auf alle Zonen zugreifen können. "Mit lua alle Zonen des Wherigos erfassen“ zeigt wie man automatisch alle Zonen erfasst und in ein Array namens
Haben wir alle Zonen greifbar, so messen wir unsere eigene Position mit
Diese Entfernung wird in der neu geschaffene Eigenschaft
Für die technisch versierten Leser sei erläutert, dass bei jedem
Beim Verlassen der Methode
Bleibt noch die Frage warum in Zeile 11
Nachdem die Zonen nach Entfernung sortiert sind, werden alle Zonen deaktiviert und anschließend die n nähesten Zone aktiviert. Damit aber nachher im Spiel nicht der Effekt auftritt, dass nacheinander die aktiven Zonen verschwinden um dann langsam wieder aufzutauchen, erweitern wir das Zonenobjekt um ein weiteres Attribute
Zeile 30 bis 32 stellt sicher, dass es zu keinem Fehler kommt wenn mehr Zonen erlaubt sind als Zonen im Spiel freigeschaltet sind (beim Start darf der Spieler nur zwei Zonen sehen, das Oregon würde aber 5 verkraften) Um die Sortierfunktion aufrufen zu können, bedarf es ein wenig Vorbereitung und Pflege der Zonen. So muss man beim Start des Spieles für alle Zonen den Wert
Außerdem darf beim Freischalten einer Zone dieses Attribute nicht vergessen werden, sonst wird dises bei dem timergesteuerten Nähecheck nie einbezogen.
Zum Schluss noch ein paar Worte zur Performance: Gerade die
Weitere Infos zum Thema herstellerspezifische Spielsituationen findet ihr im Geoclub Thread Spielverlauf durch Geräteabfrage bestimmen und im WherigoBuilder-Wiki.
Als Oregon Nutzer aber auch als Wherigo-Programmierer ist man bestimmt schon des Öfteren über das Problem gestolpert, dass die Garmin-Hardware einfach nicht mehr auf Höhe der Zeit und somit viel zu langsam ist. Recht deutlich wird dies, wenn in einem WIG recht viele Zonen gleichzeitig aktiv sein sollen. Im Geoclub liest man von maximal sieben Zonen, die das Oregon gerade noch so vertragen soll. Meine 300er Version funktionierte zwar auch noch mit 9 gleichzeitig aktiven Zonen, doch die Reaktionsfähigkeit inkrementierte in den Minutenbereich. Auf deutsch: Will man ne Zone, eine Person auswählen oder einfach nur den Bildschirmtext mit "OK" bestätigen muss man darauf gefasst sein, dass das Gerät erst nach 30 bis 60 Sekunden reagiert. Von Spielvergnügen ist da schon lange keine Rede mehr und die Gefahr eines Absturtzes steigt ebenso an. Es muss also Abhilfe her. Die einfache Lösung lautet daher: Nie so viele Zonen gleichzeitig aktiv schalten.
Das ist natürlich meistens nicht so einfach möglich. Besonders bei dynamischen Spielen, wo der User selbst entscheiden kann, wo er hingehen möchte scheint dies erstmal unmöglich. Was aber möglich ist, dass nur die nächsten n (z.B 5) Zonen angezeigt werden. Die Idee dabei ist, dass man die Zonen nach Entfernung zum Spieler sortiert und die ersten n Zonen angezeigt werden. Ein Timer kann alle paar Sekunden überprüfen, welche Zonen am Nähesten liegen und entsprechend den Active-Status umsetzen. Einfach gesprochen, doch wie wird es umgesetzt.
Als Voraussetzung muss man auf alle Zonen zugreifen können. "Mit lua alle Zonen des Wherigos erfassen“ zeigt wie man automatisch alle Zonen erfasst und in ein Array namens
zones
steckt.
Haben wir alle Zonen greifbar, so messen wir unsere eigene Position mit
Player.ObjectLocation
.
Anschließend iterieren wir über alle Zonen und messen die Entfernung des Spielers zur Zone (also zum Mittelpunkt zone.OriginalPoint
).
Diese Entfernung wird in der neu geschaffene Eigenschaft
DistanceToPlayer
gespeichert (Lua ist hier sehr großzügig und erlaubt eine
Erweiterung der
Objekte um neue Attribute zur Laufzeit, da Objekte intern auf Tabellen umgesetzt werden) bevor wir die Zone in die distTable
einfügen.
Zeile 18 bis 20 definiert einen Komparator, der in Zeile 21 der Tabelle zum Sortieren mitgegeben wird.
Für die technisch versierten Leser sei erläutert, dass bei jedem
table.insert
das neue Element mit dem ersten Element der bestehenden
Tabelle verglichen wird. Dazu wird die Vergleichsoperation aufgerufen, die wir oben definiert haben. Ist der Vergleich positiv (hier die Entfernung zum
Spieler ist kleiner), so wird das neue Element an die aktuelle Stelle eingefügt und die nachfolgenden Elemente eins weiter nach hinten geschoben. Resultiert
aus dem Boolean-Vergleich false, so wird das neue Element mit dem zweiten Element der Tabelle verglichen, u.s.w. bis entweder eine Stelle im Vergleich true
liefert oder das Ende der Tabelle erreicht ist.
Beim Verlassen der Methode
buildSortedActiveZoneMap()
wird die nach Entfernung sortierte Tabelle der Zonen zurückgeliefert.
Bleibt noch die Frage warum in Zeile 11
zone.Active2
und nicht zone.Active
verwendet wird. Die Antwort darauf ist relativ
simple.
Active2
signalisiert nicht, dass die Zone gerade aktiv ist, sondern dass sie zu den Zonen gehört, die aktiv sein dürfen. (Manche Zonen werden
ja erst im Laufe des Spieles freigeschaltet). Auch Active2
gehört zu den Attributen, die wir zur Laufzeit einfach an das lua-Objekt Zone
anhängen.
Nachdem die Zonen nach Entfernung sortiert sind, werden alle Zonen deaktiviert und anschließend die n nähesten Zone aktiviert. Damit aber nachher im Spiel nicht der Effekt auftritt, dass nacheinander die aktiven Zonen verschwinden um dann langsam wieder aufzutauchen, erweitern wir das Zonenobjekt um ein weiteres Attribute
Active3
. Dadurch bleibt für bereits aktive Zonen, die immer noch nahe genug sind der Status erhalten und wecheselt nicht von zone.Active
= true
auf false
und wieder zurück auf true
. Sieht nicht sehr schön aus im Oregon.
Zeile 30 bis 32 stellt sicher, dass es zu keinem Fehler kommt wenn mehr Zonen erlaubt sind als Zonen im Spiel freigeschaltet sind (beim Start darf der Spieler nur zwei Zonen sehen, das Oregon würde aber 5 verkraften) Um die Sortierfunktion aufrufen zu können, bedarf es ein wenig Vorbereitung und Pflege der Zonen. So muss man beim Start des Spieles für alle Zonen den Wert
Active2
initialisieren, da sonst der Vergleich in Zeile 11 fehlschlagen würde. Außerdem darf beim Freischalten einer Zone dieses Attribute nicht vergessen werden, sonst wird dises bei dem timergesteuerten Nähecheck nie einbezogen.
Zum Schluss noch ein paar Worte zur Performance: Gerade die
table.sort
Funktion ist sehr rechenintensiv und kostet viel CPU. Man sollte auf
Geräten wie Oregon also vorsichtig damit sein. Je weiter die Zonen voneinander entfernt sind, desto seltener muss der Timer den Vergleich auslösen. Wenn ich
mindestens ne Minute brauche um die nächste Zone zu erreichen, so reicht es aus, alle 30 Sekunden zu aktualisieren. Sind dagegen meine Zonen nur 20 Meter
entfernt, ist es besser das Interval auf 2 oder 3 Sekunden zu stellen.
Jetzt ist dieses Problem ja hauptsächlich ein Garmin Problem, da die meisten Nicht-Oregon-Cacher mit dem Smartphone unterwegs sind und da das
Hardwareproblem nicht so entscheidend ist. Es wäre folglich schön, wenn man diesen Workaround auf die Garminserie einschränken können.
Dies kann über die Abfrage des Environments geschehen. Dort sind viele nützliche Infos enthalten, u.a. die Geräteplatform. Diese lässt sich mit Env.Platform
abfragen und lautet bei Garmin Geräte "Vendor 1 ARM9". Diese Abfrage lässt sich nutzen um zu entscheiden, ob man den ZoneChecker-Timer startet und nicht. Wird er nicht gestartet, so werden keine Zonen deaktiviert und es kommt wieder zum alten Verhalten. Ob das sinnvoll und übersichtlich ist, hängt natürlich von der Spielidee ab.
Weitere Infos zum Thema herstellerspezifische Spielsituationen findet ihr im Geoclub Thread Spielverlauf durch Geräteabfrage bestimmen und im WherigoBuilder-Wiki.