Wie berechnet man den Vektor eines Abfangens?

11

Gegeben sind ein zweidimensionaler Raum und 1 freundliches Raumschiff, das stillsteht. Ein Feind bewegt sich NICHT direkt zum freundlichen Schiff mit bekannter tatsächlicher Position, Geschwindigkeit und Richtung.

Das freundliche Schiff will sich in Schussweite bringen, um den Feind zu bekämpfen.

Eigentlich setze ich nur einen direkten Vektor auf die tatsächliche Position des sich bewegenden Schiffes und berechne ihn in jedem Frame neu, was zu einer Art "rundem" Flugweg führt.

Was ich möchte, ist, einen direkten und geraden Weg zu der Position zu setzen, die der Feind (vermutlich) haben wird, wenn die Schussentfernung erreicht ist, vorausgesetzt, dass der Feind bis dahin seinen Kurs nicht ändert.

Als erste und "einfache" Implementierung würde es ausreichen, wenn wir davon ausgehen, dass der Freund in kürzester Zeit von 0 auf max beschleunigen kann.

Bevorzugte Implemantation wäre eine, die die Beschleunigungsfähigkeiten des Freundes berücksichtigt und weiß, wann ein Abfangen aufgrund der Geschwindigkeit unmöglich ist. Es sollte für jede Startgeschwindigkeit funktionieren, nicht nur aus dem Stand. Ein Plus wäre, wenn es sogar das Bremsen in Betracht zieht (das Kämpfen mit Lichtgeschwindigkeit ist im gegebenen Universum sehr energieeffizient).

NobbZ
quelle

Antworten:

5

Wenn ich Ihre Frage verstehe, möchten Sie nicht, dass das Schiff zum Ziel steuert, sondern in einer geraden Linie fliegt, die das Ziel abfängt. Ich mache ein Tower-Defense-Spiel, das im Grunde das gleiche Bedürfnis nach einer Turmkugel hat. Ein Turm möchte eine Waffe so abfeuern, dass die Kugel ein sich bewegendes Ziel abfängt, solange es Geschwindigkeit / Richtung nicht ändert. Ich habe es mit einer quadratischen Gleichung gelöst. Hier ist ein Pseudocode:

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second

Ich fand, dass dies so gut funktioniert, dass ich keine Kollisionserkennung für den Schuss benötigte ... Ich konnte mich darauf verlassen, dass jeder Schuss ein Volltreffer traf, unabhängig von Entfernung / Richtung / Geschwindigkeit des Ziels, solange diese Faktoren konstant blieben.

Steve H.
quelle
Nach Ihrer Beschreibung scheint dies das zu sein, wonach ich suche, zumindest der einfache Weg, eine sofortige Beschleunigung auf Höchstgeschwindigkeit anzunehmen. Ich werde mir das abends genauer ansehen. Nehme ich richtig an, dass Vector.Dot das Punktprodukt der to-Vektoren zurückgibt?
NobbZ
Hmmm ... Ich habe das jetzt in Rubin gemacht, aber da scheint etwas nicht zu stimmen. Jedes Mal, wenn ich es versuche, wird eine Ausnahme ausgelöst, da der Ausdruck im sqrt etwas Negatives ergibt und daher außerhalb der Grenzen liegt. Wie kann ich damit umgehen? Entschuldigung für die Frage, aber ich kann sie nur verwenden, aber verstehe die Konzepte hier nicht, bis mir jemand einen Rat gibt.
NobbZ
Das Beispiel stammt aus diesem Buch: amazon.com/…
Steve H
1
Ich weiß nicht, ob dies hilft, aber hier ist ein Python-Code, der das Gleiche bewirkt. moddb.com/mods/wicmw/tutorials/…
Steve H
OK, ich verstehe die dahinter stehende Lochmathematik immer noch nicht, aber danke für den Python-Code, sagte mir die Dokumentation, dass mein Freund zu langsam ist, um aufzuholen, wenn es einen negativen Wert im sqrt gibt. Nachdem ich meine Testwerte angepasst habe, erhalte ich einige Ergebnisse. Vielen Dank für Ihre Hilfe.
NobbZ
6

Ich schlage vor, Sie untersuchen das Lenkverhalten. Besonders Verfolgung . Der Quellcode befindet sich in der OpenSteer- Implementierung oder in einem Buch wie " Programmierspiel AI anhand eines Beispiels " (ISBN 13: 978-1556220784).

bummzack
quelle
Verfolgung scheint Wissen über das Ziel zu benötigen und steuert darauf zu, aber ich kenne das Ziel nicht wirklich. Ich weiß, wo der Feind jetzt ist, ich kenne seine Geschwindigkeit und seine Richtung. Jetzt möchte ich wissen, in welche Richtung es gehen muss, um den Feind auf seinem Weg zum Ziel so schnell und schnell wie möglich abzufangen. Wie bereits erwähnt, kann die Beschleunigung zunächst ignoriert werden, dies würde sogar viel Verarbeitungszeit im Vergleich zur tatsächlichen Version sparen ... Mit dem neuen Modell muss ich nur neu berechnen, wenn der Gegner ein "Kurswechsel" -Ereignis auslöst, nicht für jedes " hasmoved "-event wie ich es jetzt mache.
NobbZ
Ja, was Sie beschreiben, ist Verfolgung. Es kennt das Ziel nicht. Es macht eine Vorhersage basierend auf dem aktuellen Standort, der Geschwindigkeit und der Richtung der "Feinde"
Bummzack
Dann habe ich die Beschreibung falsch verstanden, ich werde sie mir morgen genauer ansehen.
NobbZ
Ich habe das Dokument erst vor ein paar Minuten gelesen. Verfolgung ist NICHT das, wonach ich suche. Es ist wie bei meiner eigentlichen Implementierung, außer dass es auf die Position des nächsten Frames abzielt. Ich muss den neuen Kurs immer noch in jedem Frame neu berechnen und der Kurs führt zu einer Kurve. Aber was ich will, ist die direkte Linie, die davon ausgeht, dass der Feind weder Geschwindigkeit noch Kurs ändert, bis sich beide treffen. Wenn dies immer noch nicht klar genug ist, versuche ich nach der Arbeit zu zeichnen, was ich will. Aber trotzdem danke für die Links. Ich denke, ich kann dies irgendwo anders im Projekt verwenden.
NobbZ
@NobbZ Es tut mir leid, dass meine Antwort nicht hilfreich war. Sie sollten Ihre Frage vielleicht entsprechend bearbeiten, da Aussagen wie: "Ich weiß, dass im Falle einer Änderung der Geschwindigkeit oder des Kurses des Feindes jede Berechnung wiederholt werden muss" irreführend sein können. Wenn Sie das tun, würden Sie am Ende haben das "Verfolgungs" -Lenkverhalten.
Bummzack