Koordinatenberechnung

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

McThyzer

Betreff: Koordinatenberechnung

BeitragFr, Feb 18, 2011 21:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo!

Ich wollte in meinem Programm mit Projektilen arbeiten, welche die Gegner auf direktem Weg verfolgen und treffen.

Jedoch habe ich mehrere Probleme festgestellt...

Mein erster anlauf war folgender:

Code: [AUSKLAPPEN]
Local nrotation = ATan2( (Monster.data[targetM_ID].y - y), (Monster.data[targetM_ID].x - x) ) + 90
      Local bonusx:Double = Sin(nrotation) * tempo   
      Local bonusy:Double = Cos(nrotation) * tempo


bonusx wird zur x- und bonusy zur y-Koordinate addiert.

Aber es hat absolut nicht so geklappt wie es sollte...

Mit folgendem Code klappt es halbwegs

Code: [AUSKLAPPEN]
      Local nrotation = ATan2( (Monster.data[targetM_ID].y - y), (Monster.data[targetM_ID].x - x) ) + 90
      Local bonusx:Double = Sin(180 - nrotation) * tempo   
      Local bonusy:Double = Cos(180 - nrotation) * tempo


Der gesamte Code:
(Ausschnitt des "Projektil"-Types)

Variablen erklärung:
Monster.data[targetM_ID].y/x - Geben die x/y Koordinaten des aktuell anvisiertem Ziels zurück.

Funktionen erklärung:
Destroy() - Ist ebenfalls bestandteil des "Projektil"-Types, es ersetzt die Werte des Aktuellen Projektils mit denen des Letzten Projektils und verringert die Anzahl der Projektile um 1 (Zerstört quasi das jetzige Projektil)

Code: [AUSKLAPPEN]
   Method Update()
      Local nrotation = ATan2( (Monster.data[targetM_ID].y - y), (Monster.data[targetM_ID].x - x) ) + 90
      Local bonusx:Double = Sin(180 - nrotation) * tempo   
      Local bonusy:Double = Cos(180 - nrotation) * tempo
      
      If Abs(x - Monster.data[targetM_ID].x) > bonusx Or Abs(y - Monster.data[targetM_ID].y) > bonusy Then   
         rotation = nrotation            
         x :+ bonusx
         y :+ bonusy
         
         If Monster.data[targetM_ID].HP <= 0 Then
            Destroy()
         EndIf   
      ElseIf Abs(x - Monster.data[targetM_ID].x) =< bonusx And Abs(y - Monster.data[targetM_ID].y) =< bonusy Then   
         Monster.data[targetM_ID].HP :- dmg
         Destroy()         
      EndIf   
   EndMethod



Aber dennoch ist es fehlerhaft. Und zwar gibt es 2 Buggs die abundzu auftreten:

1.) Das Projektil befindet sich quasi im Gegner, wird aber nicht "Destroyed", weil es vermutlich um genau 1 pixel zu weit entfernt ist.

2.) Das Projektil befindet sich in einer beliebigen entfernung genau Oben-Links vom Gegner und bewegt sich mit dem selben Tempo wie der Gegner (behält also die Entfernung Konstant bei), bis der Gegner die Richtung nach Links wechselt.

Midimaster

BeitragSa, Feb 19, 2011 2:32
Antworten mit Zitat
Benutzer-Profile anzeigen
aus deinem Code ist leider sehr wenig erkennbar...Ich vermute mal bonusx und bonusy werden immer zur Position des Projektils (Koordinaten X? und Y?) dazugezählt.

Das bringt mich auf eine Idee...

Da du bonusx aus SIN() und einem tempo errechnest, könnte tempo so groß sein, das das Projektil einen Moment vor der Kollision noch vor dem Objekt und im nächsten Moment schon hinter dem Objekt ist.

Hier hilft oft eine feinere Auflösung:

BlitzMax: [AUSKLAPPEN]

Method Update()
Local nrotation = ATan2( .....
Local bonusx:Double = Sin(180 - nrotation) * tempo
Local bonusy:Double = Cos(180 - nrotation) * tempo
rotation = nrotation
For Local I%=1 To 10
x :+ bonusx/10
y :+ bonusy/10
If Monster.data[targetM_ID].HP <= 0 Then
Destroy()
EndIf
If Abs(x - Monster.data[targetM_ID].x) =< bonusx And .....Then
Monster.data[targetM_ID].HP :- dmg/10
Destroy()
EndIf
Next
End Method
 

McThyzer

BeitragSa, Feb 19, 2011 14:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Klappt leider nicht, da

Code: [AUSKLAPPEN]
bonusx/10


Kleiner als 1 ist, und man kann ja nicht um 0.15 Pixel bewegen... Sad

Noch eine andere Idee?

Was genau ist denn wenig erkennbar? Hab doch ziemlich alles erklärt.

Zitat:
Ich vermute mal bonusx und bonusy werden immer zur Position des Projektils (Koordinaten X? und Y?) dazugezählt.


Zitat:
bonusx wird zur x- und bonusy zur y-Koordinate addiert.
 

Jumper

BeitragSa, Feb 19, 2011 15:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Aber natürlich geht das. Du mußt in deinem Beispiel:
x :+ bonusx/10
y :+ bonusy/10
x, y, bonusx und bonusy nur als Float oder Double deklarieren.

Ana

BeitragSa, Feb 19, 2011 15:19
Antworten mit Zitat
Benutzer-Profile anzeigen
ich muss gestehen, dass ich deinen Code als solches nicht so ganz nachvollziehen kann, von daher werde ich mich allgemein halten.

Das Problem ist, dass du eine Bewegung von A nach B willst, wobei A und B sich verändern können oder? Also Projektil (A) fliegt durch die Gegend, und Ziel (B) wandert herum?

Dann kannst du die x und y Koordinaten als Vektor verstehen und mit atan2 die Rotation des Images bestimmen und den Vektor normieren in dem du ihn durch die Distanz teilst.
Das Beispiel ist mal eine Methode des Projektiels und B das Ziel
BlitzMax: [AUSKLAPPEN]
Methode Move()
Local vx# = (x - b.x)
Local vy# = (y - b.y)
Local dis# = Sqr(vx^2 + vy^2)

rotation = (ATan2(vy,vx)
vx:/dis
vy:/dis
x:- vx * Geschwindigkeit
y:- vy * Geschwindigkeit
End Methode


Ich hoffe ich hab das Problem jetzt nicht falsch verstanden ...
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

mpmxyz

BeitragSa, Feb 19, 2011 15:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Dein Ansatz sieht so sauberer aus:
BlitzMax: [AUSKLAPPEN]
Local nrotation = ATan2( (Monster.data[targetM_ID].y - y), (Monster.data[targetM_ID].x - x) )
Local bonusx:Double = Cos(nrotation) * tempo
Local bonusy:Double = Sin(nrotation) * tempo

Atan2(y,x) nimmt nämlich an, dass der Winkel 0 nach rechts zeigt und im Uhrzeigersinn weitergeht.
Ich kann mir außerdem vorstellen, dass das Kollisionsproblem mit dem Verschieben der "Bewegung" vor den If-Block gelöst werden kann:
BlitzMax: [AUSKLAPPEN]
rotation = nrotation            
x :+ bonusx
y :+ bonusy
If Abs(x - Monster.data[targetM_ID].x) > Abs(bonusx) Or Abs(y - Monster.data[targetM_ID].y) > Abs(bonusy) Then
If Monster.data[targetM_ID].HP <= 0 Then
Destroy()
EndIf
ElseIf Abs(x - Monster.data[targetM_ID].x) =< Abs(bonusx)And Abs(y - Monster.data[targetM_ID].y) =< Abs(bonusy) Then
Monster.data[targetM_ID].HP :- dmg
Destroy()
EndIf

Ansonsten hängt die Kollisionsabfrage der Bewegung hinterher. (Das Ziel wird vorher bewegt, oder?)
Es ist im Allgemeinen besser, wenn das Zielen, die Bewegung und die Kollisionsabfrage getrennt werden.
Dann kommen solche Synchronisationsprobleme nicht mehr vor.
Selbst jetzt könnte es bei anderen Sachen Probleme geben.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer
 

McThyzer

BeitragSa, Feb 19, 2011 15:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Jumper hat Folgendes geschrieben:
Aber natürlich geht das. Du mußt in deinem Beispiel:
x :+ bonusx/10
y :+ bonusy/10
x, y, bonusx und bonusy nur als Float oder Double deklarieren.


Das hat (glaub ich) geklappt, jedenfalls hat es 10min am stück fehlerfrei funktioniert.

Danke! Smile

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group