Wie berechnet man den Schusswinkel und die Schussgeschwindigkeit, um ein sich bewegendes Ziel zu treffen?


11

Ich entwickle ein 2D-Android-Spiel und mache einen Zielalgorithmus für KI-Projektile, um Feinde entweder auf einem Pfad oder in freier Bewegung zu treffen. Im Moment wird nur berechnet, wo sich das Ziel nach einer Entfernung befindet, und es wird ein Projektil abgefeuert, um es in dieser Entfernung zu treffen. Dies bedeutet natürlich, die Projektilgeschwindigkeit zu variieren, um das Ziel zu erreichen.

Hat jemand Tipps für einen einfachen Algorithmus (optimal), um zu berechnen, wann das Projektil feuern muss und wohin es zielen muss, wenn es sich nur mit konstanter Geschwindigkeit fortbewegen kann? Angenommen, das Projektil ist doppelt so schnell wie das Ziel?

Der einzige Weg, den ich mir vorstellen kann, ist das Suchen und scheint ziemlich groß zu sein.



@ JohnMcDonald: nicht sehr verwandt, da es sich um parabolische Projektile handelt, nicht linear. Das ist viel näher: gamedev.stackexchange.com/questions/4995/...
e100

Antworten:


13

In einem von mir erstellten Tower-Defense-Spiel habe ich eine quadratische Gleichung verwendet, um den Schnittpunkt und damit den Zielpunkt vorherzusagen. Das folgende Zielcode-Snippet geht davon aus, dass sich der Feind mit konstanter Geschwindigkeit und Richtung bewegt. Es wird auch davon ausgegangen, dass sich das Projektil mit einer bekannten konstanten Geschwindigkeit bewegt (kann eine beliebige Geschwindigkeit sein, muss aber dem Algorithmus bekannt sein).

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

Da es auch den Zeitpunkt des Aufpralls bestimmt, habe ich einfach gewartet, bis die Zeit abgelaufen ist, um die Aufprallgrafiken an der Position des Ziels zu diesem Zeitpunkt aufzurufen. Es ist keine Kollisionserkennung erforderlich, um Treffer zu bestimmen.


"Keine Kollisionserkennung erforderlich, um Treffer zu ermitteln." - Wenn die Ziele gezwungen sind, ihre Geschwindigkeit und Richtung beizubehalten. --- Wenn sie jedoch eine aktive KI haben oder schlimmer noch, der Spieler sind und sich bewegen können, nachdem der Schütze geschossen hat, führt die zeitliche Ausrichtung Ihrer Treffer anstelle der Kollisionserkennung zu Ihrer Spielerbasis wird als einige böse Bugs / Pannen wahrnehmen.
XenoRo

@ TheLima yup, genau wie es im 2. Satz der Antwort steht. ;-)
Steve H

Dies ist fast perfekt für mein Szenario, aber wie würden Sie diese beiden zusätzlichen Variablen berücksichtigen: Beschleunigung für das Projektil, Bewegung des Turms selbst?
Jack

Was aist 0? Dies führt zu einer Ausnahme durch Division durch Null, aber was bedeutet dies in Bezug auf die Variable t? sollte es als "eine sehr große Zahl" betrachtet werden oder was wäre der beste Fall?
Firelynx

Gibt es ein gutes Buch, das in die Intuition dahinter geht? Ich bin neugierig, woher du
wusstest,

4

Geben Sie hier die Bildbeschreibung ein

Die KI, der Standort des Ziels während des Abschusses des Projektils und der eventuelle Standort des Ziels zum Zeitpunkt des Todes bilden ein Dreieck. Hier sollten Sie bereits wissen:

  1. Seitenlänge a, die die Projektilgeschwindigkeit ist
  2. Seitenlänge b, die die Zielgeschwindigkeit ist
  3. Der Bewegungswinkel des Ziels der Bewegung des Ziels.

Sie haben drei Teile des Dreiecks, einen SSA-Fall, also lösen Sie es so

  1. Finden Sie den Winkel B basierend auf dem Bewegungswinkel und dem Ort der KI
  2. Verwenden Sie das Sinusgesetz, um den Winkel A zu finden

Winkel A sollte es Ihnen ermöglichen, den Winkel zu bestimmen, in dem das Projektil abgefeuert werden soll.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.