Ich habe ne Frage für mein AKS.
Die Charas sollen dem Helden folgen.
Ist nun aber ein Gegner innerhalb eines 5-Tiles-Radius,so sollen die Chars anfangen,sich den Gegner zu nähern.
Wie berechne ich den 5-Tiles Radius und frage ab,ob ein Gegner innerhalb diesen Radius ist?
Ich würde sagen: Du addierst den Betrag der Differenz der X-Koordinaten mit dem Betrag der Differenz der Y-Koordinaten von Held und Gegner und guckst ob da ein Wert kleiner als 5 rauskommt.
Also:
X.Abstand=HeldX-GegnerX
Y.Abstand=HeldY-GegnerY
wenn X.Abstand < 0
=>X.Abstand*(-1)
wenn Y.Abstand < 0
=>Y.Abstand*(-1)
Gesamtabstand=X.Abstand+Y.Abstand
Dann kannst du abfragen, ob der Gegner im Radius ist.
Das musst du natürlich für alle Helden und alle Gegner machen...
Edit: Ich seh grad, dass ich konsequent deine Variablen ignoriert habe. Ich weiß nicht was mir Radius+ oder Radius- genau gemeint sein soll...
Es geht dir doch quasi darum den Abstand zweier Chars zu bestimmen, oder?
Edit2: inwiefern unterscheidet sich R.D.s Methode von meiner? Naja Wayne...
erstmal danke.
So wie du es beschrieben hast,ist der Radius nur Kreuzfähig.
Ich möchte es aber Rechteck-fähig machen.
links ist dein Vorschlag,Rechts so,wie ich es haben möchte.
€dit:
Denkfehler,ist doch richtig^^
Geändert von Engel der Furcht (27.12.2009 um 16:29 Uhr)
Also ich denke um den Kreuzradius auf den Quadratradius zu erhöhen musst du das Skript von Dasdull erweitern :
[...]
=>Y. Abstand*(-1)
If X. Abstand kleiner gleich 5
=>Call Event Charas greifen an
Else Case
If Y.Abstand kleiner gleich 5
=>Call Event Charas greifen an
Zumindest denke ich das es so funktioniert...
könnte aber auch sein das gerade totaler Bullshit war weil ich das selbst noch nie gemacht habe
Edit:
Die Rechnung von Dasdull geht mmn nicht auf weil wenn mann die beiden Abstände addiert kann man auf Werte kommen die über 5 sind...
Und wenn man abfragt ob der Gesamtabstand unter 10 liegt kann X.Abstand auch 8 und Y.Abstand 0 sein...
Es sei denn du hasts ausprobiert...
Und ich merk grad das meins auch nicht funktioniert
Ich editier meinen Lösungsvorschlag geich ochmal neu rein bis mir was besseres eingefallen ist
Wenn du den X- und Y-Abstand berechnet hast musst du dann eigentlich
so wie ich mir das jetzt im Kopf denke nicht viel machen, sondern dann nur
beides hintereinander abfragen.
Also bei...
...müsste das so weitergehen:
Man könnte theoretisch das noch auf mehr Arten erweitern indem du einfach
getrennte Maximalabstände für X und Y benutzt womit es wirklich ein gantz
normales Rechteck werden kann, zB 13x7 oder auch auf eine Linie, wo nur
X oder Y auf Gleichheit geprüft wird und der andere Wert egal ist ausser die
Linie ist begrenzt.
EDIT: Um zu erfahren wo im Quadrat denn nun das Event ist, da wir nun
wissen es steht drin oder tuts nicht, benutze die Abstandswerte erneut,
--
Solange es hier falschzitierende Ärsche gibt, dulde ich keinerlei Zitatboxen, die von mir sein sollen.
Wobei das *(-1) eigentlich nicht nötig ist bzw. das Ergebnis sogar verfälscht. Eigentlich muss man nur die Gegner-Koordinaten von den Held-Koordinaten abziehen.
Und dann das was im 2. Codeblock von MagicMaker steht. Die Vorzeichen sollte man ruhig beibehalten, denn abhängig von denen könnte man z. B. bestimmen wo genau der Gegner steht und eine "Step toward Event"-Methode scripten.
Wenn du abfrage wilslt ob zb ein Held in einem Radius ist machst du das:
Objekt X - Held X
Objekt Y - Held Y
Wenn Objekt X oder Y im Minus bereich, dann *-1
Objekt X * Objekt Y
Dann abfrage ob X in einem bestimmten Bereich ist, zb bei 2, würde die Bedingung war, wenn der Held 2 oder weniger Felder weit weg steht:
Meine Version, ist dann kreisförmig. (Ist imho für ein AKS realistischer, vorallem mit Scene X und Y)
Maker Code:
Zitat von EasyEventExporter
- SCRIPT -
<> Change Variable: [294] = X position on map (tiles) of event #1
<> Change Variable: [295] = Y position on map (tiles) of event #1
<> Change Variable: [294] -= X position on map (tiles) of hero
<> Change Variable: [295] -= Y position on map (tiles) of hero
<> Fork Condition: If Variable [294] <= -1 then ...
. <> Change Variable: [294] *= -1
. <>
: End of fork
<> Fork Condition: If Variable [295] <= -1 then ...
. <> Change Variable: [295] *= -1
. <>
: End of fork
<> Change Variable: [294] += V[295]
<> Fork Condition: If Variable [294] <= V[385] then ...
. <> Comment: WAHR
. <>
: End of fork
...
See, it's really that simple^^ Das Ganze geht auch mit Scene X und Y, musste halt größerer Bereich machen :/
Den Wert umzukehren, also die *(-1)-Zeilen, hab ich mir erst nachher
gedacht, das war nachdem ich mir dachte "das muss doch andersrum sein",
weil ich da nicht nach Abstandslogik sondern Koordinaten ging und deswegen
lieber die negativen Werte oben und links wollte, auf die andere Art sind sie
ganz klar andersrum.
hero=27 - event=23 = 4, er steht 4 Felder weiter links, nach meiner
Rechnung SOLLTE es so gehen, dass nachher die Zahl umgedreht wird,
also -4 wird, aber ich musste es natürlich irre verdreht wie ich bin, wenn
ichs nicht praktisch teste, in die falsche Zeile schreiben, denn das sollte
erst nach beiden Zeilen passieren und nicht dazwischen:
27 - 23 * -1 = -4 27 * -1 - 23 = -50
Da aber das von R.D. eh wirklich simpler und besser scheint, ist es eh egal.
--
Solange es hier falschzitierende Ärsche gibt, dulde ich keinerlei Zitatboxen, die von mir sein sollen.
@R.D.
Irgendwie verstehe ich deine Methode noch nicht. Zuerst werden die Koordinaten voneinander abgezogen und das Ergebnis gegebenenfalls mal -1 genommen. Das ist soweit klar. Dann werden die beiden Abstände addiert. Mit welchem Wert vergleichst du sie danach?
Nehmen wir mal an, der Gegner hätte die Koordinaten (10,10) und der Held die Koordinaten (6,6). Nach deinem System hätten wir dann zunächst als Ergebnis zweimal 4. Beides addiert gibt 8. Nun wollen wir aber den Abstand 5 haben, wie kommst du jetzt von der 8 auf den? Und inwiefern ist das System kreisförmig?
R.D. prüft bei seiner Methode nach, ob der errechnete Wert gleich oder kleiner ist als die Varialbe V[385]. Diese Variable muss vorher vom Skripter auf einen bestimmten Wert gesetzt werden. Je höher dieser Wert, desto größer auch der Radius. Ich habe es auch erst mit ein paar Werten proberechnen müssen um es zu verstehen.
Stellen wir uns einfach mal vor, wir hätten die Variable V[385] auf "8" gesetzt:
G [10,10] ; H [6,6] => 4+4 = 8 ==> Der Gegner ist im Radius des Helden!
G [9,10] ; H [6,6] => 3+4 = 7 ==> Der Gegner ist im Radius des Helden!
G [12,8] ; H [6,6] => 6+2 = 8 ==> Der Gegner ist im Radius des Helden!
G [11,10] ; H [6,6] => 5+4 = 9 ==> Der Gegner ist nicht im Radius des Helden!
Oder probiers einfach mal selber aus. Ist ja gar nicht viel Aufwand zum skripten^_-
Ja stimmt und nach welcher Formel müsste dann der Wert der Variable berechnet werden? Es wäre ja nicht praktisch, wenn man bei größeren Entfernungen erst rumprobieren müsste. Aber ich denke mal diese Technik und der rechteckige Radius nehmen sich nicht wirklich viel, Tilemovement ist ja auch alles andere als genau. In der Praxis wird man nicht viel davon bemerken, dass die Randfelder nicht berücksichtigt werden.
Die Variable V[385] ist wie Stoep sagt nur ein Setwert, der vom Benutzer Entwickler bestimmt werden kann, wen ndu 2 eingibst, dann muss der Held 2 oder weniger Felder weit weg sein und man ist "Wahr". (Ich habe das aus meinem Projekt entnommen und ein wenig verändert und dabei vergessen, dass ich da 2 varis vergleiche xD)
Hero (10,4)
Obj (5,5)
X: 5-10 = -5 * -1 = 5
Y: 5-4 = 1
X + Y = 6
Das tuhe ich, damit ich im "UMKREIS" abfragen kann, das hielt ich damals als ic hes gebraucht habe für besser, da man sich ja auch von Schräg nähern kann, usw :/
Und ich sagte ja, das muss man dann auf Scene X und Y abstrahieren. Dann kann man die V[385] berechnen lassen indem man das ganze umkehrt und nicht mehr nachschaut ob der Held in ein der Nähe eines Objektes ist, sondern ob das Objekt in einem bestimmten Umkreis ist, alles möglich
(Btw ist das ein wirklich netter Trick, den man im Studium lernt (was für mich ein wenig zu spät kam xD)
Auf zur Nato!/o
Edit:
Sry, mehr Zeit habe ich das nicht zu erklären und das Dull hat btw das Gleich wie ich, nur aus Held-Sicht xD (das hat er mir gerade unter Tränen in einer Pn gebeichtet)
Man kann auch einen Kreisradius nehmen, da würde ich aber dann nicht mit X/Y-Koordinate des Helden/Gegners sondern mit der Szenen-Koordinate des Helden/Gegners rum hantieren.
Dabei muss (xH − xG)^2 + (yH − yG)^2 <= r^2 wahr sein, damit der Gegner im Angriffsbereich ist.
(Legende:
xH, yH : Szenen-Koordinate des Helden
xG, yG : Szenen-Koordinate des Gegners
r : Radius in Pixeln (in dem Falle: r=5*16=80)
Ich weiß aber nicht wie fehleranfällig und wie schnell das ganze im Maker ist,
am besten und schnellsten ist der Rechteck-Radius.
Wenn man einen Kreisradius nehmen will, sollte man für die Berechnung den PowerPatch nehmen, da es da schneller geht (arbeitet mit Gleitkommazahlen in der schnelleren und genaueren FPU-Erweiterung des CPU, im Gegensatz: der Maker nur mit Ganzzahlen im CPU).
@R.D.: Dein Ansatz ist rautenförmig und nicht kreisförmig. Bei genügend großen Abständen kann sich der Unterschied auch im Kästchenraum des RPG Makers deutlich bemerkbar machen. Wer eine Kreisform will ist mit dem Satz des Pythagoras: a²+b²=c² besser beraten, den niR-kun in seinem Ansatz anwendet.
Zitat von niR-kun
Ich weiß aber nicht wie fehleranfällig und wie schnell das ganze im Maker ist,
am besten und schnellsten ist der Rechteck-Radius.
...
Inwiefern sollte es fehleranfällig sein?
Zitat von niR-kun
Wenn man einen Kreisradius nehmen will, sollte man für die Berechnung den PowerPatch nehmen, da es da schneller geht (arbeitet mit Gleitkommazahlen in der schnelleren und genaueren FPU-Erweiterung des CPU, im Gegensatz: der Maker nur mit Ganzzahlen im CPU).
Ein Kreis ist eine Linie von Punkten mit gleichem Abstand zu einem Mittelpunkt. Der Satz von Pythagoras liefert eine Formel für den Abstand zweier Punkte in einer Ebene. Setze für c einen beliebigen Radius r ein und du erhältst mit allen Lösungspaaren (a, b) alle Punkte auf der Kreislinie des Kreises mit dem Radius r. Nun geht es darum festzustellen, ob der Abstand zwischen Punkt (x, y) und Punkt (xi, yi) kleiner (oder gleich) r ist, ob also (xi, yi) innerhalb (oder auf) der Kreislinie liegt, die durch den Mittelpunkt (x, y) und den Radius r definiert ist. Für alle Punkte innerhalb (oder auf) der Kreislinie gilt also (xi-x)² + (yi-y)² <= r² mit dem Referenzpunkt/Mittelpunkt (x, y) und dem Testpunkt (xi, yi). Ist der Term (xi-x)² + (yi-y)² größer als r², liegt (xi, yi) außerhalb der Kreislinie, ansonsten innerhalb, oder auf ihr.
Ich habe bereits mehrmals sowohl Bresenhams Kreis-, als auch sein Linien-Algorithmus und Xiaolin Wus Abwandlungen davon und Ähnliches implementiert, weiß also durchaus über die rasterbedingten Probleme Bescheid. Der Punkt ist: Sie sind hier irrelevant, da es nicht um das Zeichnen eines Kreises geht, sondern um Abstandsmessung. Selbst für die Rasterisierung eines Kreises wäre es in vielen Fällen akzeptabel, der Grund für den Bresenham-Algorithmus und gegen den naiven a²+b²=c²-Ansatz ist eher die Performance, als die genauere Rasterung. Die Hälfte aller möglichen Probleme ist außerdem bereits mit dem kleiner-gleich-Vergleich eliminiert.
Ich weiß schon was Ganzzahlen und was Gleitpunktzahlen sind. Habe übrigens auch einiges an Erfahrung in Low-Level-Optimierung. Es ging mir um die pauschale Aussage, dass Integerarithmetik langsamer sein soll als Gleitpunktarithmetik. (Ungenau ist Integerarithmetik übrigens auch nicht grundsätzlich. Addition, Subtraktion und Multiplikation sind absolut genau. Alleine bei der Division können Probleme auftauchen, da die Information hinter dem Komma verloren geht.) Das ist nämlich alles andere als gegeben und in vielen Fällen eher das Gegenteil. Auf Glauben sollte man keine technischen Entscheidungen basieren, sondern nur auf Messungen. Selbst wenn es einen Unterschied gibt, so ist dieser mit sehr hoher Wahrscheinlichkeit so marginal, dass er nur bei Millionen oder mehr von Rechenoperationen messbar ist, für den Fall einer einfachen Abstandsmessung also vollkommen irrelevant ist.
Ich habe bereits mehrmals sowohl Bresenhams Kreis-, als auch sein Linien-Algorithmus und Xiaolin Wus Abwandlungen davon und Ähnliches implementiert, weiß also durchaus über die rasterbedingten Probleme Bescheid. Der Punkt ist: Sie sind hier irrelevant, da es nicht um das Zeichnen eines Kreises geht, sondern um Abstandsmessung. Selbst für die Rasterisierung eines Kreises wäre es in vielen Fällen akzeptabel, der Grund für den Bresenham-Algorithmus und gegen den naiven a²+b²=c²-Ansatz ist eher die Performance, als die genauere Rasterung. Die Hälfte aller möglichen Probleme ist außerdem bereits mit dem kleiner-gleich-Vergleich eliminiert.
...
Ich als Programmierer (arbeite z.T. mit Assembler, größtenteils mit Turbo-/Free-Pascal [Schule] und neustens auch mit ActionScript) kenne das Problem zu genüge. Unter Turbo Pascal habe ich vor 2 Jahren mal eine eigene Grafik-Unit für VESA geschrieben (wenn ich heute mal einen Blick drauf werfe staune ich immer noch darüber wie Mächtigkeit und Funktionsumfang der Unit).
Zitat von Kyuu
Ich weiß schon was Ganzzahlen und was Gleitpunktzahlen sind. Habe übrigens auch einiges an Erfahrung in Low-Level-Optimierung. Es ging mir um die pauschale Aussage, dass Integerarithmetik langsamer sein soll als Gleitpunktarithmetik. (Ungenau ist Integerarithmetik übrigens auch nicht grundsätzlich. Addition, Subtraktion und Multiplikation sind absolut genau. Alleine bei der Division können Probleme auftauchen, da die Information hinter dem Komma verloren geht.) Das ist nämlich alles andere als gegeben und in vielen Fällen eher das Gegenteil. Auf Glauben sollte man keine technischen Entscheidungen basieren, sondern nur auf Messungen. Selbst wenn es einen Unterschied gibt, so ist dieser mit sehr hoher Wahrscheinlichkeit so marginal, dass er nur bei Millionen oder mehr von Rechenoperationen messbar ist, für den Fall einer einfachen Abstandsmessung also vollkommen irrelevant ist.
...
Da muss ich dir recht geben, aber wegen den beschränkten und langsamen Rechenmitteln des RM2K/3 ist es besser auf den PowerPatch zurück zu greifen. Besonders sollte man bedenken, dass das Spiel auch auf älteren Systemen (die die Minimalanforderung des Makers erfüllen, so ab Pentium3 @500MHZ) flüssig laufen soll, nicht nur auf den neueren PCs (@2GHz oder mehr). Deswegen sollte alle für-nicht-Programmierer-möglichen Wege der Optimierung unternommen werden.
Ich denke, dass das genug über die Optimierung, Ganzzahlen und Gleitpunktzahlen ist. Das ganze verwirrt Engel der Furcht und die anderen, die das lesen.
Wieder back on topic ...
PS. Danke, ich lerne wieder etwas aus dem Streitgespräch. Andere unterschätzt man doch immer viel zu schnell