PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wurzel ziehen mit dem Maker - und praktische Anwendungsideen



Itaju
18.09.2012, 21:14
Hallo meine Lieben,

heute bin ich auf etwas gestoßen, das ich gerne verbreiten möchte, auch wenn es vermutlich dem einen oder anderen bekannt sein sollte.

Und zwar, wie man mit dem RPG Maker (praktisch) die Wurzel aus einer Zahl zieht und wofür das in der Praxis gut sein kann.


Beginnen möchte ich, wie ich auf das Problem gestoßen bin:

Stellen wir uns vor wir haben eine Geräuschquelle, zum Beispiel einen tropfenden Wasserhahn, als Event auf einer Karte. Wir wollen, dass wir das Tropfgeräusch nur hören, wenn sich der Spieler in einem bestimmten Abstand zu diesem Event befindet.

Früher habe ich das folgender Maßen geregelt: Die X und Y-Koordinaten beider Events werden subtrahiert. Im Falle eines negativen Ergebnisses mit -1 multipliziert (um stets ein Positives zu haben) und dann beide Werte addiert.

H = Held
W = Wasserhahn
O = Leeres Feld

OOW
HOO

Vereinfacht gesagt: der Wasserhahn liegt 2 Felder rechts und 1 nach oben, was einem Abstand von 2+1 = 3 entspricht.

Problem ist, dass sich jetzt die Felder mit einem bestimmten Abstand immer rautenförmig um das Zentrum bewegen.

Im Beispiel seht ihr, dass die Zahl 3 in einem Viereck und nicht in einem Kreis herum angebracht ist.


765434567
654323456
543212345
432101234
543212345
654323456
765434567



Ich wollte allerdings lieber erreichen, dass die Felder z.B. mit dem Abstand 3 zum Zentrum eher kreisförmig angeordnet sind:


0033300
0300030
3000003
3000003
3000003
0300003
0033300


Am besten zu Berechnen wäre dies mit Sinus-Satz, da wir bereits zwei Koordinaten wissen, allerdings besitzt der Maker keine Sinus bzw. Cosinus-Funktion und die Berechnung damit nicht möglich.

Da fiel mir auf, dass wir zur Koordinatenbestimmung ja mit rechten Winkeln arbeiten, also der Satz des Pythagoras gilt: a^2+b^2 = c^2

a und b sind bekannt, nur benötigen wir für c eine Funktion eine Wurzel zu ziehen, die der Maker ebenso nicht besitzt.

Also habe ich geschaut, ob es Verfahren gibt, die auf den Grundrechenarten basieren und eine Wurzel annähern können und bin auf das hier gestoßen:

http://de.wikipedia.org/wiki/Heron-Verfahren

Ein Algorithmus also, der das Ergebnis annähert und immer genauer annähert, je häufiger man ihn durchführt.
Ich möchte euch jetzt die Komplexität des Wikipediartikels ersparen und hier kurz erläutern, wie ich es im Maker umgesetzt habe:

Vorgeplänkel

V1 = HeldX
V2 = HeldY
V1 - ObjektX
V2 - ObjektY
V1*V1 // das hier ist a^2
V2*V2 // das hier ist b^2
V1+V2 //a^2+b^2 = c^2.

//V1 ist jetzt die Zahl aus der die Wurzel gezogen werden muss. Für den ersten Schritt des Algorithmus wähle ich x0 =1
V2 = V1 // Ich benutze V2 zum Rechnen, damit V1 den Ursprungswert behält und nicht verändert wird
V2 + 1
V2 / 2

V3 = V2 // V3 nimmt jetzt das Ergebnis, das in diesem Abschnitt wiederverwendet wir
V2 = V1
V2 / V3
V2 + V3
V2 / 2

Diese letzten 5 Schritte können beliebig oft wiederholt werden um das Ergebnis zu verfeinern. Allerdings muss bedacht werden, dass der Maker bei Divisionen keine Kommastellen berücksichtigt, daher ist die Annäherung gewissen Ungenauigkeiten unterworfen.

Ich lasse das ganze viermal durchlaufen und bekomme dadurch schon exzellente Ergebnisse.

Ich hoffe, ihr konntet verstehen, was ich hier vorgestellt habe, und dass es dem einen oder anderen beim umsetzen der Projekte hilfreich sein kann.

RPG Hacker
18.09.2012, 22:25
Erinnert mich an etwas, das ich MagicMaker mal geschickt (http://bin.smwcentral.net/u/3394/PointMath.png) habe. Allerdings hat er es mit Destiny umgesetzt, was natürlich wesentlich leichter war, weil Wurzeln schon drin sind.
Bei solchen Sachen merkt man aber, dass der RPG Maker doch wesentlich eingeschränkter ist, als es einem anfangs vorkommt. Selbst für einfachste Effekte in einem zweidimensionalen Videospiel braucht man nämlich oft schon Wurzelfunktionen, trigonometrische Funktionen und was weiß ich nicht.

Itaju
18.09.2012, 22:30
Jo, das rechts ist ja einfach nur eine Umstellung des Satz des Pythagoras. Das, was ich jetzt dazu beisteuere ist eine einfache Wurzelannäherung in den Grundrechenarten.
Das Links ist ja für solche Zwecke irrelevant, im Moment fällt mir nix ein, wo der Winkel von Bedeutung ist.

RPG Hacker
18.09.2012, 23:40
Naja, wie da beschrieben kann man das linke z.B. für einen Kompass verwenden (wenn man zwei Punkte auf der Map hat, vom einen zum anderen zeigen will und die Rotation für die Nadel-Grafik in Grad angeben muss). Aber ja, ich bezog mich natürlich speziell auf das rechte. Und na klar ist das auch nur der Pythagoras. Deswegen sage ich ja, dass es mich an diesen Thread erinnert. ;)
Ein Unterschied bei meinem Beispiel ist höchstens, dass man die Berechnung auch ganz leicht auf ein 3D-Spiel übertragen kann, indem man einfach die Z-Koordinate dazunimmt. Bin mir jetzt aber nicht sicher, ob es nicht eine Art Phythagoras für die dritte Dimension gibt.

Davy Jones
19.09.2012, 11:15
Gibt es dafür einen Beispielskript?

Thuin8
19.09.2012, 13:11
Kommt mir doch sehr bekannt vor, weil ich das ebenfalls mal für die Berechnung von Abständen gebaut habe. Ist aber leider nur eine Annäherung, und problematisch wird es glaube ich auch deshalb, weil der RM keine Kommazahlen beherrscht, wenn ich mich nicht irre. Aber eine schöne Erklärung, die vielleicht dem ein oder anderen hilft Abstände genauer anzugeben.
Allerdings empfehle ich, wenn solche Berechnungen benötigt werden, ehrlich gesagt etwas wie den DestinyPatcher, mit dem man das in einer Zeile code erledigt hat. :)

CapSeb
21.09.2012, 00:46
Wenn man nicht allgemein eine Formel für den Abstand sucht, sondern für einen speziellen Fall schon weiß, welchen Radius man benutzen möchte, kann man einfach das Wurzelziehen beim Pythagoras weglassen.

Bsp.: Möchte man überprüfen, ob fünf Felder Abstand zwischen Ziel und Held erreicht werden, betrachtet man den waagrechten Abstand x zwischen Ziel und Held und den senkrechten Abstand y zwischen Ziel und Held. Berechnet wird nun, ob x²+y² < 25 ist. Das Wurzelziehen kann einfach ignoriert werden, da man als Vergleichswert nicht 5 sondern 5² = 25 verwendet.

Auch wenn man allgemein eine Funktion schreiben will, funktioniert diese Methode. Allerdings kann sie nur zurückgeben, ob der nötige Abstand unterschritten wurde oder nicht. Wie weit man sich von der Grenze entfernt befindet, wird nicht wiedergegeben. Vorgehen mit d als Grenze für den Abstand:

- Ausgangsfrage: Ist der Abstand zwischen A und B kleiner als d?
- Sei x der waagrechte Abstand, y der senkrechte Abstand zwischen A und B.
- Berechne q=x²+y².
- Berechne z=d².
- Antwort: Ist q<z, dann ist der Abstand zwischen A und B kleiner als d, sonst nicht.