![]() |
Weg im 2D Koordinatensystem merken
Hallo,
ich habe ein kleines Spiel. Und zwar ist man eine Linie die in eine richtig gezeignet wird, man kann jedoch die "Direction" über den Winkel bestimmen. Also einfach gesagt - die Linie geht einfach einem Winkel nach den man mit den Pfeiltasten anpassen kann :D Dafür benutze ich eine einfache Funktion:
Delphi-Quellcode:
Ausgeführt wird ganz einfach:
function GetNextPosition(X, Y, Length : real; Angel: integer): TRealPoint;
var Orientation: TAngleOrientation; x2,y2:real; a, b, alpha: Double; begin a := Length * Sin(DegToRad(Angel)); b := Sqrt(Sqr(Length) - Sqr(a)); if (Angel > 0) AND (Angel < 91) then begin Orientation := aoRight; end else if (Angel > 90) AND (Angel < 181) then begin Orientation := aoBottom; Angel := Angel - 90; end else if (Angel > 180) AND (Angel < 271) then begin Orientation := aoLeft; Angel := Angel - 180; end else if (Angel > 270) AND (Angel < 360) then begin Orientation := aoTop; Angel := Angel - 270; Angel := abs(Angel - 90); end; case Orientation of aoRight : begin x2 := X + b; y2 := Y + a; end; aoBottom : begin x2 := X - b; y2 := Y + a; end; aoLeft : begin x2 := X - b; y2 := Y + a; end; aoTop : begin x2 := X + b; y2 := Y + a; end; end; Result := RealPoint(x2, y2); end;
Delphi-Quellcode:
Mit der Funktion krieg ich also den Punkt wo der Spieler sich jetzt befinden sollte.
Position := GetNextPosition(Position.x, Position.y, DeltaTime * Speed, Direction);
Nun möchte ich den ganzen weg abspeichern. Das habe ich bisher mit einer abfrage gemacht, die alle 100ms den Punkt speichert und die Linie wird dann mit DrawPolyline gezeichnet. Nun könnt ihr euch die Probleme bestimmt schon vorstellen.
Welche Möglichkeiten gibt es dies eleganter zu lösen? Freundliche Grüsse |
AW: Weg im 2D Koordinatensystem merken
Du überschreibst alle 100ms die Länge des bisher seit dem letzten Richtungswechsel zurückgelegten Weg. Beim Richtungswechsel merkst Du dir den neuen Winkel. Die bisher zurückgelegte STrecke (die Länge des letzten Segmentes) schreibst Du dann an die Stelle des letzten Richtungswechsels.
PS: Wieso ist GetNextPosition keine Methode von TRealPoint? Und wieso nimmst Du nicht Double statt Real? ;-) |
AW: Weg im 2D Koordinatensystem merken
Im Prinzip keine so wirklich, da die Bewegung völlig frei ist. Man könnte noch statt der Koordinaten die Richtungsänderungen nur bei wirklicher Änderung aufzeichnen, braucht dann aber zusätzlich noch einen Zeit-Index. Ob das also am Ende günstiger kommt, hängt davon ab wie hoch der Anteil an gerade gelassenen Abschnitten im Mittel ist.
Wenn dir beim "Replay" die Genauigkeit nicht 100%ig wichtig ist, könntest du auch noch ein gröberes Raster aufzeichnen, und nachher mit einem Catmull-Rom Spline interpolieren. Das vermindert zumindest die Eckigkeit, und da der Spline immer durch die Punkte verläuft könnte man da recht simpel das Aufnahmeraster nach Wunsch anpassen, bis man einen guten Mittelweg zwischen Präzision und Datenmenge hat. Noch zwei Anmerkungen zu deinem Code: 1) Dein Winkel heisst derzeit Engel ;) 2) Warum änderst du den Engel in dem if-then-Konstrukt, wenn du nachher nicht mehr darauf zugreifst? (Delphi sollte hier auch einen entsprechenden Hinweis ausgeben.) |
AW: Weg im 2D Koordinatensystem merken
Hmm... Im Grunde genommen läuft mein Vorschlag darauf hinaus, nur die Richtungsänderungen zu protokollieren. Dazu wird bei jeder Richtungsänderung nur der neue Winkel und die alte zurückgelegte Strecke benötigt. Das sind 2 Werte. Zusätzlich merkt man sich noch alle 100ms den zurückgelegten Weg, den man natürlich *nicht* in einer Historie ablegt. Somit ist diese Version genau dann platzsparender, wenn der Richtungswechsel seltener als alle 100ms vorkommt, wovon auszugehen ist, da die Richtungswechsel manuell durchgeführt werden.
Delphi-Quellcode:
Type
TVector = Record Distance, Direction : Double; end; ... // Alle 100 ms Player.Last.Distance := TotalDistance(CurrentPosition, Player.LastPosition); // Bei Richtungswechsel Player.Last.Distance := TotalDistance(CurrentPosition, Player.LastPosition); if Player.Last.Distance > 0 then Player.History.Add(Player.Last); Player.Last.Distance := 0; Player.Last.Angle := NewAngle; Player.LastPosition := CurrentPosition; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz