Pathfinding funktionoert mit Types nicht

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Ratchet

Betreff: Pathfinding funktionoert mit Types nicht

BeitragFr, Jan 07, 2005 18:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe hier im Forum einen Code gefunden um ein Objekt zu den Mauskoordinaten wandern zu lassen. Ist halt diese Sache mit Winkelberechnung und so. Jetzt hab ich es in BlitzMax konventiert, klappt auch wunderbar.
Jetzt habe ich mir einen Type erstellt der meine Spielfigur darstellen soll und die selbe Funktionalität als Methode eingebaut. Das Problem: Die Spielfigur, in diesem Fall ein Rechteck, wandert nicht richtig. Befindet sich der Spieler z.B. an Position 0, 0 und klicke ich an eine Stelle die nicht allzuweit von X entfernt ist, also z.B. 20, 100, bewegt sich das Viereck erst senkrecht nach unten und erst ca. ab der Hälfte der Strecke zum eigentlichen Punkt. Aus irgendeinem Grund funktioniert die Winkelberechnung nicht richtig. Ich vermute das es etwas mit der Genauigkeit zu tun hat. Irgendein Wert muß in Float oder Int sein, hab aber schon alles probiert. Ich find den Fehler einfach nicht. Am besten mal ansehen um zu sehen was ich mein.

Erstmal der Code aus dem Forum (benötigt noch "bbtype.bmx" und "bbvkey.bmx" die beim Import von bb Dateien von blitzmax erstellt werden)
Code: [AUSKLAPPEN]
Import "bbtype.bmx"
Import "bbvkey.bmx"

Graphics 800,600,0
' SetBuffer BackBuffer()
 Const ESC = 1, Bildwiederholung = 50, debug =1
 Global frameTimer=CreateTimer(Bildwiederholung)
 Global posX#= 100,PosY# = 100
 While Not VKeyDown(ESC)
 
 DrawRect Int(posX+0.5),Int(PosY+0.5),50,50
 If MouseDown(1) ' neues ziel zuweisen
   x_Ziel = MouseX()
   Y_Ziel = MouseY()
 End If

   grad = Objekt_richtung_grad(x_Ziel ,Y_Ziel,posX ,posY)
     posX_Speed# = Cos(grad )*2 ' 1 = Speed je nachdem wie viele Pixel schnell
     posY_Speed#  = Sin(grad )*2
 
 posX = posX  + posX_Speed
   If  posX_Speed < 0 And posX  < x_Ziel Then' abfrage ob ziel erreicht
    posX_Speed = 0
    posX = x_Ziel
   Else If posX_Speed > 0 And posX  > x_Ziel Then
    posX_Speed = 0
    posX = x_Ziel
   EndIf
 
 posY = posY  + posY_Speed
   If  posY_Speed < 0 And posY  < y_Ziel Then' abfrage ob ziel erreicht
      posY_Speed = 0
      posY = y_Ziel
   Else If posY_Speed > 0 And posY  > y_Ziel Then
     posY_Speed = 0
     posY = y_Ziel
   EndIf
   
 If debug Then
 DrawText "posX :      "+ posX , 500,360
 DrawText  "posY:       "+ posY , 500,380
 DrawText "posX Speed: "+ posX_Speed , 500,400
 DrawText "posY Speed: "+ posY_Speed , 500,420
 DrawText  "x_Ziel :     "+  x_Ziel , 500,440
 DrawText  "y_Ziel :     "+  y_Ziel , 500,460
 DrawText  "Grad :       "+  grad , 500,480
 EndIf
 
 WaitTimer(frameTimer)
    Flip
    Cls
 
 Wend
 End
 Function Objekt_richtung_grad(Zielpunkt_X,Zielpunkt_Y,Ausgangspunkt_X,Ausgangspunkt_Y )
 Waagerechte  = Zielpunkt_X -Ausgangspunkt_X
 Hoehe              = Zielpunkt_Y -Ausgangspunkt_Y
   '0 grad ist hier nach links und im Uhrzeigersinn wird er höher
 grad =ATan2(Hoehe ,Waagerechte)
 grad = (grad+360)+360
 Return grad
 
 End Function


Nun meine Code der nicht so richtig will:

Code: [AUSKLAPPEN]
Graphics 800, 600, 0

Player:TPlayer = TPlayer.Create()

While Not KeyHit(KEY_ESCAPE)
   Cls
   If MouseHit(1)
      Player.GoX = MouseX()
      Player.GoY = MouseY()
   End If


   Player.UpdatePosition()
   Player.Draw()

   DrawText  "MouseX :     "+ MouseX(), 500, 500
   DrawText  "MouseY :     "+ MouseY(), 500, 520

   Flip
Wend

Type TPlayer
   Field X, Y: Float
   Field GoX, GoY: Float
   Field Speed: Int

   Function Create: TPlayer()
      NewPlayer: TPlayer = New TPlayer
      NewPLayer.Speed = 2
      Return NewPlayer
   End Function

   Method UpdatePosition()
      Local w, h: Int
      Local a: Int
      Local MoveX: Float
      Local MoveY: Float
      
      If (Self.X <> Self.GoX) Or (Self.Y <> Self.GoY) Then
         'Winkel berechnen
         w = Self.GoX - Self.X
         h = Self.GoY - Self.Y
         a = (ATan2(h, w) + 360) + 360
         DrawText(a, 200, 200)

         'X und Y Verschiebung berechnen
         MoveX = Cos(a) * Self.Speed
         MoveY = Sin(a) * Self.Speed
         
         'Positon neu setzen
         Self.X :+ MoveX
         Self.Y :+ MoveY
         If MoveX < 0 And Self.X < Self.GoX Then
            MoveX = 0    
            Self.X = Self.GoX
         Else If MoveX > 0 And Self.X > Self.GoX Then
            MoveX = 0
            Self.X = Self.GoX
         End If         
         If  MoveY < 0 And Self.Y < Self.GoY Then
            MoveY = 0
            Self.Y = Self.GoY
         Else If MoveY > 0 And Self.Y > Self.GoY Then
            MoveY = 0
            Self.Y = Self.GoY
         End If
      End If
   End Method

   Method Draw()
      DrawRect(Self.X, Self.Y, 32, 32)
      DrawText(Self.GoX + " " + Self.GoY + " " +Self.Speed, 50,50)
      DrawText(Self.X +" "+Self.Y, 50, 70)
   End Method
End Type
  • Zuletzt bearbeitet von Ratchet am Fr, Jan 07, 2005 20:31, insgesamt einmal bearbeitet
 

Demon

BeitragFr, Jan 07, 2005 20:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Du musst X und Y im Feld als Float deklarieren.
Das liegt ganz einfach daran, dass entweder MoveX oder -Y bei Speed=2 Werte unter 1 zurückgeben und bei der nachfolgenden Addition nicht berücksichtigt werden (deshalb hast du diese eckigen Bahnen).

[Edit]
Ich seh grad, dass GoX und GoY da auch noch mit drin hängen, also auch die zu Float machen Smile.

[/Edit]
Don't drink and derive!

Ratchet

BeitragFr, Jan 07, 2005 20:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, im Original sind diese Werte auch Floats, das bringt aber nichts!
Habs mal oben in meinem Quelltext geändert, das zuerstgepostete war grad ne Testversion.

Ich hab die einzelnen Zwischenwerte jetzt sogar mal miteinander verglichen, die sind immer gleich und müssten stimmen, ich weiß einfach nicht was ich übersehe.
 

Demon

BeitragFr, Jan 07, 2005 21:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Seeehr merkwürdig.

Mal 'ne Frage am Rande, wozu rechnest du bei a 20000 Mal +360?
360° sollten den Sinus und Cosinus nicht signifikant verändern Very Happy.

Ach ja, und das Self kannste überall weglassen Wink.
Don't drink and derive!

Ratchet

BeitragFr, Jan 07, 2005 21:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Das doppelte +360 kommt aus dem Original. Hab auch schon gemerkt das einmal reicht Very Happy
Bin nun nicht das große Mathegenie und habs deswegen so gelassen.

Ich weiß echt nicht weiter, das kann doch nicht angehen...
 

Demon

BeitragFr, Jan 07, 2005 21:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Ughhh Confused

Hab' den Fehler Smile.
Ein kleiner Denkfehler von uns beiden... Es wird nur Y als Float deklariert, aber nicht X.
Der richtige Code wäre:

Code: [AUSKLAPPEN]

Graphics 800, 600, 0

Player:TPlayer = TPlayer.Create()

While Not KeyHit(KEY_ESCAPE)
   Cls
   If MouseHit(1)
      Player.GoX = MouseX()
      Player.GoY = MouseY()
   End If


   Player.UpdatePosition()
   Player.Draw()

   DrawText  "MouseX :     "+ MouseX(), 500, 500
   DrawText  "MouseY :     "+ MouseY(), 500, 520

   Flip
Wend

Type TPlayer
   Field X:Float, Y: Float
   Field GoX: Float, GoY: Float
   Field Speed: Int

   Function Create: TPlayer()
      NewPlayer: TPlayer = New TPlayer
      NewPLayer.Speed = 1
      Return NewPlayer
   End Function

   Method UpdatePosition()
      Local a: Float
      Local MoveX: Float
      Local MoveY: Float
     
      If (X <> GoX) Or (Y <> GoY) Then
         'Winkel berechnen
         a = ATan2(GoY - Y, GoX - X)
         DrawText(a, 200, 200)

         'X und Y Verschiebung berechnen
         MoveX = Cos(a) * Speed
         MoveY = Sin(a) * Speed

         'Positon neu setzen
         X :+ MoveX
         Y :+ MoveY
         If MoveX < 0 And X < GoX Then
            MoveX = 0   
            X = GoX
         Else If MoveX > 0 And X > GoX Then
            MoveX = 0
            X = GoX
         End If         
         If  MoveY < 0 And Y < GoY Then
            MoveY = 0
            Y = GoY
         Else If MoveY > 0 And Y > GoY Then
            MoveY = 0
            Y = GoY
         End If
      End If
   End Method

   Method Draw()
      DrawRect(X, Y, 32, 32)
      DrawText(GoX + " " + GoY + " " +Speed, 50,50)
      DrawText(X +" "+Y, 50, 70)
   End Method
End Type
Don't drink and derive!

Ratchet

BeitragFr, Jan 07, 2005 21:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh mann, ich glaubs nicht. Da wär ich in 1000 Jahren nicht drauf gekommen! Hatte angenommen das es so wie bei Pascal funzt. Tja Max ist ja auch Basic...
Vielen Dank! Da kann ich ja endlich weiterproggen. Danke, Danke!

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group