Spielephysik (game physics): Geschossflugbahnen (Ballistik)

Die Simulation von realistisch wirkenden Geschossflugbahnen zählt zu den zentralen Gamplay-Elementen eines jeden Kriegs- oder Strategiespiels. In Vergessenheit geraten ist hingegen das früher einmal so beliebte Genre der Artillerie-Spiele, in denen nicht die KI sondern wir als Spieler dafür verantwortlich waren, die feindlichen Ziele zu treffen. Vielleicht erinnern sich noch einige von Ihnen an das kostenlose Spiel Ballerburg (Neuauflage 2001 durch Ascaron). Als Herr einer Burg trat man gegen den Computer oder einen menschlichen Gegner an und musste Runde für Runde die feindliche Burg unter Beschuss nehmen, bis einer der Burgherren durch einen direkten Treffer getötet wurde.

Verschaffen wir uns mal anhand einer Abbildung eine Übersicht über die verschiedenen Kräfte, die während des Fluges auf ein Geschoss einwirken:

















Im Wesentlichen müssen wir die folgenden drei Kräfte berücksichtigen:

  • Erdbeschleunigung
  • Luftwiderstand (Newton-Reibung)
  • Windkraft (Einfluss des Windes, Newton-Reibung)

In der Realität ist die Sache natürlich noch um einiges komplizierter, da die Projektilform einen nicht unwesentlichen Einfluss auf die Flugbahn hat. Moderne Projektile haben bei gleicher Mündungsgeschwindigkeit dank ihres geringeren Luftwiderstandes eine deutlich größere Reichweite als Kanonenkugeln, neigen jedoch aufgrund ihrer aerodynamisch besseren Formgebung zu wilden Taumelbewegungen, die Flugbahn und Reichweite völlig unvorhersagbar machen. Die Projektile müssen daher durch einen zusätzlichen Drall (Rotation um die eigene Längsachse) stabilisiert werden, bsp. mithilfe schraubenförmig gezogener Läufe. In einem Spiel werden die Projektilformen normalerweise nicht berücksichtigt und die Projektile folglich als einfache Massenpunkte aufgefasst.

Anfangsgeschwindigkeit eines Projektils

Die Vorgänge beim Abschuss eines Projektils sind vom physikalischen Standpunkt aus betrachtet viel zu kompliziert für eine Simulation im Rahmen eines Computerspiels. Für uns zählt lediglich das Ergebnis wenn das Projektil die Kanone verlässt – die Flugrichtung und die Mündungsgeschwindigkeit. Kombiniert man beides miteinander, erhält man den Anfangsgeschwindigkeitsvektor:

Anfangsgeschwindigkeit = Mündungsgeschwindigkeit*Flugrichtung

 Die Mündungsgeschwindigkeit ist abhängig vom Kanonentyp, von der Projektilmasse und ist proportional zur eingesetzten Treibladung (Schießpulver, Schießbaumwolle, usw.).
Die Anfangsflugrichtung entspricht der Ausrichtung der Kanone. Berücksichtigt man Anstell- und Schwenkwinkel der Kanone (siehe Abbildung), dann berechnet sich die Flugrichtung wie folgt:

Flugrichtung.x = cos(Anstellwinkel)*sin(Schwenkwinkel)
Flugrichtung.y = sin(Anstellwinkel)
Flugrichtung.z = cos(Anstellwinkel)*cos(Schwenkwinkel)

Simulation der Projektil-Flugbewegung

Die erste Kraft, die wir bei unserer Simulation berücksichtigen müssen, ist die Erdanziehung:

Gewichtskraft = Projektilmasse*Fallbeschleunigung

Für die Berechnung des Luftwiderstands (Newton Reibung) ohne Windeinflüsse wählen wir den folgenden Ansatz:

Luftwiderstand = -Flugrichtung*Wirkungsfaktor*
                |Projektilgeschwindigkeit

Hierbei berücksichtigt der Wirkungsfaktor sowohl den Luftwiderstandswert des Projektils als auch dessen Querschnittsfläche in Flugrichtung.

Möchte man darüber hinaus auch die Windeinflüsse berücksichtigen, so müssen wir zunächst die Anströmgeschwindigkeit des Projektils berechnen:

Anströmgeschwindigkeit = -Projektilgeschwindigkeit + vWind

Luftwiderstand = Anströmrichtung*Wirkungsfaktor*
                |Anströmgeschwindigkeit

Kombiniert man die einzelnen Kräfte miteinander, dann ergibt sich die Gesamtkraft, die momentan auf das Geschoss einwirkt, bzw. dessen momentane Beschleunigung:

Gesamtkraft = Gewichtskraft + Luftwiderstand

Beschleunigung = Gesamtkraft/Projektilmasse

Mithilfe der Beschleunigung können wir nun die Geschwindigkeit und Position des Projektils im aktuellen Frame berechnen. Hierbei greifen wir auf das einfache Euler-Verfahren zurück, dessen Genauigkeit für unsere Zwecke völlig ausreichend ist. Nachfolgend ist die Berechnung von zwei Simulationsschritten pro Frame skizziert:

long NumSimulationStepsPerFrame = 2;

float SimulationTime = FrameTime/NumSimulationStepsPerFrame;

for(long i = 0, i < NumSimulationStepsPerFrame; i++)
{
      // hier die Beschleunigung ermitteln:
      [...]

      // neue Geschwindigkeit berechnen:
      Velocity += Acceleration*SimulationTime;

      // neue Position berechnen:
      Position += Velocity*SimulationTime;
}