Haftungsausschluss: Es gibt wahrscheinlich andere und bessere Möglichkeiten, dies zu tun. In beiden Fällen werde ich mitteilen und beschreiben, wie ich vor einiger Zeit mit diesem Problem umgegangen bin, was für mich in Ordnung war.
Ich habe vor ein paar Jahren ein 2D-Top-Down-Autospiel für ein Universitätsprojekt implementiert, und wenn ich mich richtig erinnere, habe ich diesen Artikel als Ausgangspunkt verwendet, obwohl ich ihn letztendlich stark vereinfacht und all das fallen gelassen habe. " Rad "Modelliermaterial zugunsten einer einzigen Karosserie für das Auto. Was ich jedoch verwendet habe, war etwas Ähnliches wie die KillOrthogonalVelocity
Methode, die Sie dort finden können, um die seitliche Reibung aufzubringen.
Hier ist ein kleines Video, wie es sich herausstellte. Es wird eine gewisse seitliche Reibung angewendet, die auch davon abhängt, ob ich den Handbremsknopf benutze oder nicht, und das Auto, das ich für das Video verwendet habe, driftet auch deutlich stärker als die anderen. Dies war jedoch steuerbar. Es hatte auch einen LKW ohne seitliche Bewegung und sehr steife Bedienelemente.
Ich war mit den Ergebnissen nie ganz zufrieden, aber es war genug für meine Bedürfnisse. Denken Sie daran, dass ich meine Physik nicht auf echte Fahrzeugbewegungen oder ähnliches gestützt habe. Ich habe nur gezwickt und Dinge ausprobiert, bis es sich richtig anfühlte.
Seitwärtsreibung
Um ein paar Details zur Implementierung zu geben, habe ich bei der Anpassung dieser Methode an mein Projekt eine Variable hinzugefügt, mit der ich genau steuern konnte, wie viel von der Seitengeschwindigkeit ich töten würde, als Wert zwischen 0 und 1. Dadurch konnte ich das Handling des Autos und die Drift fein einstellen. Hier ist die in XNA übersetzte und vereinfachte Methode:
public static void KillOrthogonalVelocity(Car car, float drift = 0f)
{
Vector2 forwardVelocity = car.Forward * Vector2.Dot(car.Velocity, car.Forward);
Vector2 rightVelocity = car.Right * Vector2.Dot(car.Velocity, car.Right);
car.Velocity = forwardVelocity + rightVelocity * drift;
}
Wie Sie sehen, verwende ich Vektoren und lineare Algebra, keine Trigonometrie. Sie müssen sie also an Ihre Bedürfnisse anpassen. Beide car.Forward
und car.Right
sind normalisierte Vektoren, die in diese bestimmte Richtung zeigen.
Gas, Bremsen, Lenkung
Abgesehen davon war der einzige andere relevante Teil, wie ich die Kräfte auf das Auto ausübte, um es zu bewegen und zu lenken:
- Beschleunigen und Bremsen war einfach. Es geht nur darum, eine Kraft in die Richtung auszuüben, in die das Auto gerade zeigt, oder umgekehrt.
Die Lenkung hatte dagegen ein paar Tricks. Die Lenkung erfolgte durch Anlegen eines Drehmoments an das Auto (ich habe Box2D verwendet, dies war also ein einfacher Methodenaufruf), aber die Leistung dieses Drehmoments hing von einigen Faktoren ab, insbesondere:
- Beim Bremsen habe ich das Drehmoment um 25% erhöht, um schärfere Kurven fahren zu können.
if(braking || handbraking) torque *= 1.25
- Beim Rückwärtsfahren habe ich auch das Drehmoment umgekehrt, um die richtigen Steuerungen zu erhalten.
if(reverse) torque *= -1
- Wenn das Auto unter einer bestimmten Geschwindigkeitsschwelle fuhr, ließ ich es weniger als gewöhnlich lenken.
if(speed < 2.0f) torque *= (speed / 4.0f)
Rufen Sie dann einfach die KillOrthogonalVelocity()
Methode auf, um die Endgeschwindigkeit anzupassen und sie weniger wie ein Raumschiff als vielmehr wie ein Auto zu verhalten.