Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 20 von 28

Thema: X/Y-Radius berechnen

  1. #1

    Users Awaiting Email Confirmation

    X/Y-Radius berechnen

    Hallo Leute!

    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?

    PS:
    Ich habe folgende Varis:

    CharX
    CharY
    CharXRadius+
    CharXRadius-
    CharYRadius+
    CharYRadius-

  2. #2
    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...

    Geändert von dasDull (27.12.2009 um 18:33 Uhr)

  3. #3

    Users Awaiting Email Confirmation

    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)

  4. #4
    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

    Geändert von Stummboy (27.12.2009 um 16:40 Uhr)

  5. #5
    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...
    Code:
    <>Var[xxxx:X.Abstand] = HeldX
    <>Var[xxxx:X.Abstand] *= -1
    <>Var[xxxx:X.Abstand] -= GegnerX
    <>Var[xxxx:Y.Abstand] = HeldY
    <>Var[xxxx:Y.Abstand] *= -1
    <>Var[xxxx:Y.Abstand] -= GegnerY
    ...müsste das so weitergehen:
    Code:
    <>Var[xxxx:Maxi.Abstand] = 5 <- Maximaler Abstand
    <>Var[xxxx:Maxi.Negativ] = -5 <- Als negativer Wert
    <>If Var[xxxx:X.Abstand] <= [xxxx:Maxi.Abstand]
     <>If Var[xxxx:X.Abstand] >= [xxxx:Maxi.Negativ]
      <>If Var[xxxx:Y.Abstand] <= [xxxx:Maxi.Abstand]
       <>If Var[xxxx:Y.Abstand] >= [xxxx:Maxi.Negativ]
        <>Note: Hier wird alles in einem Quadrat eingegrenzt.
        <>Note: Es wurde geprüft, ob sich das Event im umliegenden
        <>Note: Quadrat von 11x11 Feldern steht (5*2+1).
    Code:
    -- -- -- -- -- -5 -- -- -- -- --
    -- -- -- -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- -- -- --
    -5 -- -- -- -- [] -- -- -- -- +5
    -- -- -- -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- -- -- --
    -- -- -- -- -- -- -- -- -- -- --
    -- -- -- -- -- +5 -- -- -- -- --
    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,


    Geändert von MagicMaker (27.12.2009 um 16:50 Uhr)

  6. #6
    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.

    Abstand-X = Held-X - Gegner-X
    Abstand-Y = Held-Y - Gegner-Y

    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.

  7. #7
    Geht viel einfacher.

    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 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 :/

    Geändert von R.D. (27.12.2009 um 17:58 Uhr)

  8. #8

    Users Awaiting Email Confirmation

    Ah,R.D.s scheint mir am simpelsten.
    Vielen Dank.

  9. #9
    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.

  10. #10
    @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?

  11. #11
    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^_-

    Gruß
    Stoep

  12. #12
    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.

  13. #13
    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)

    Geändert von R.D. (28.12.2009 um 06:04 Uhr)

  14. #14
    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)

    Code:
    <>Var[xxxx:xTemp] SET,Hero SceneX
    <>Var[xxxx:xTemp] -, Gegner SceneX
    <>Var[xxxx:xTemp] *, Var[xxxx:xTemp]
    <>Var[xxxx:yTemp] SET,Hero SceneY
    <>Var[xxxx:yTemp] -, Gegner SceneY
    <>Var[xxxx:yTemp] *, Var[xxxx:yTemp]
    <>Var[xxxx:rCheck] SET, Var[xxxx:xTemp]
    <>Var[xxxx:rCheck] +, Var[xxxx:yTemp]
    <>Var[xxxx:rHoch2] SET, Var[xxxx:r]
    <>Var[xxxx:rHoch2] *, Var[xxxx:rHoch2]
    <>Fork Conditions: Var[xxxx:rCheck] <= Var[xxxx:rHoch2]
     <>Comment: WAHR
    :ELSE Case
     <>Comment: FALSCH
    :END Case
    <>
    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).

  15. #15
    @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 Zitat von niR-kun Beitrag anzeigen
    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 Zitat von niR-kun Beitrag anzeigen
    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).
    Wie bitte?

  16. #16
    Zitat Zitat
    Wer eine Kreisform will ist mit dem Satz des Pythagoras: a²+b²=c² besser beraten, den niR-kun in seinem Ansatz anwendet.
    Für mich klingt das mehr nach Rechnung mit einem Dreieck. In der Formel steht
    ausserdem das hier: x²+y²<=

    Zitat Zitat
    [...] Szenen-Koordinate [...]
    Geht es plötzlich um Abstand auf dem Bildschirm? Bei Tiles dachte ich ja eher
    an die ganze Map.

  17. #17
    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 , liegt (xi, yi) außerhalb der Kreislinie, ansonsten innerhalb, oder auf ihr.

  18. #18
    Zitat Zitat von MagicMaker Beitrag anzeigen
    Für mich klingt das mehr nach Rechnung mit einem Dreieck. In der Formel steht
    ausserdem das hier: x²+y²<=
    Kyuu hat das in dem Post darunter ganz gut beschrieben, was ich meinte.
    Das ist die Koordinatengleichung für einen Kreis. (siehe: http://de.wikipedia.org/wiki/Kreisgleichung#Gleichungen)

    Zitat Zitat von MagicMaker Beitrag anzeigen
    Geht es plötzlich um Abstand auf dem Bildschirm? Bei Tiles dachte ich ja eher
    an die ganze Map.
    Das mit den Szenen-Koordinaten ist viel genauer, als mit den Map-Koordinaten.

    Zitat Zitat von Kyuu Beitrag anzeigen
    Inwiefern sollte es fehleranfällig sein?
    Schau dir mal das hier an: http://de.wikipedia.org/wiki/Bresenh...es_Algorithmus. Du musst dir die Map als Raster vorstellen, da gibt es natürlich Fehler und Ungenauigkeiten.

    Zitat Zitat von Kyuu Beitrag anzeigen
    Wie bitte?
    Dazu: http://de.wikipedia.org/wiki/Integer_%28Datentyp%29
    http://de.wikipedia.org/wiki/Gleitkommazahl

    Geändert von niR-kun (31.12.2009 um 20:50 Uhr) Grund: Rechtschreibfehler

  19. #19
    Zitat Zitat von niR-kun Beitrag anzeigen
    Schau dir mal das hier an: http://de.wikipedia.org/wiki/Bresenh...es_Algorithmus. Du musst dir die Map als Raster vorstellen, da gibt es natürlich Fehler und Ungenauigkeiten.
    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.

  20. #20
    Zitat Zitat von Kyuu Beitrag anzeigen
    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 Zitat von Kyuu Beitrag anzeigen
    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

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •