Pathfinding funktionoert mit Types nicht
Übersicht BlitzMax, BlitzMax NG Allgemein
RatchetBetreff: Pathfinding funktionoert mit Types nicht |
Fr, Jan 07, 2005 18:47 Antworten mit Zitat |
|
---|---|---|
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 |
Fr, Jan 07, 2005 20:12 Antworten mit Zitat |
|
---|---|---|
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 . [/Edit] |
||
Don't drink and derive! |
Ratchet |
Fr, Jan 07, 2005 20:30 Antworten mit Zitat |
|
---|---|---|
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 |
Fr, Jan 07, 2005 21:14 Antworten mit Zitat |
|
---|---|---|
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 . Ach ja, und das Self kannste überall weglassen . |
||
Don't drink and derive! |
Ratchet |
Fr, Jan 07, 2005 21:17 Antworten mit Zitat |
|
---|---|---|
Das doppelte +360 kommt aus dem Original. Hab auch schon gemerkt das einmal reicht
Bin nun nicht das große Mathegenie und habs deswegen so gelassen. Ich weiß echt nicht weiter, das kann doch nicht angehen... |
||
Demon |
Fr, Jan 07, 2005 21:30 Antworten mit Zitat |
|
---|---|---|
Ughhh
Hab' den Fehler . 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 |
Fr, Jan 07, 2005 21:42 Antworten mit Zitat |
|
---|---|---|
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! |
||
Übersicht BlitzMax, BlitzMax NG Allgemein
Powered by phpBB © 2001 - 2006, phpBB Group