Seitwärtsreibung in einem 2D-Top-Down-Renner

7

Ich habe versucht, eine Art Top-Down-Renner zu entwickeln, aber ich habe Probleme, das Auto richtig zu drehen. Im Moment ist dies der Code, mit dem ich die Position des Autos aktualisieren muss:

var power;
    if (keyboard.upKeyDown) {
        power = 1;
    } else {
        power = 0;
    }

if (keyboard.leftKeyDown) {
    this.rotate -= 0.05;
} else if (this.keyboard.rightKeyDown) {
    this.rotate+= 0.05;
}

this.velocityX += Math.cos(this.rotate) * power;
this.velocityY += Math.sin(this.rotate) * power;

var cDrag = 0.98;
this.velocityX *= cDrag;
this.velocityY *= cDrag;

this.positionX += this.velocityX;
this.positionY += this.velocityY;

Im Moment ist der Code sehr einfach, Sie halten UP gedrückt und es wird Kraft in die Richtung ausgeübt, in die Sie zeigen, wodurch es sich wie das Schiff in Asteroiden anfühlt.

Mir scheint, das nächste, was ich tun muss, ist, die Richtung, in die das Auto zeigt, mit der Richtung zu vergleichen, in die es tatsächlich fährt, und eine Seitwärtskraft anzuwenden, um es in Seitwärtsrichtung zu verlangsamen, aber auch einen Teil dieser Kraft in Vorwärtsrichtung zu übertragen Also geht es weiter in die Richtung, in die es jetzt zeigt.

Ich bin etwas verwirrt darüber, wie ich das mache, daher wäre jeder Rat sehr willkommen.

Pogo
quelle

Antworten:

9

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 KillOrthogonalVelocityMethode, 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.Forwardund car.Rightsind 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:

    1. Beim Bremsen habe ich das Drehmoment um 25% erhöht, um schärfere Kurven fahren zu können. if(braking || handbraking) torque *= 1.25
    2. Beim Rückwärtsfahren habe ich auch das Drehmoment umgekehrt, um die richtigen Steuerungen zu erhalten. if(reverse) torque *= -1
    3. 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.

David Gouveia
quelle
Vielen Dank für die Antwort. Ich habe gerade versucht, Ihren Vorschlag umzusetzen, und er scheint wirklich gut zu funktionieren. Ich werde auf jeden Fall einige der anderen Dinge ausprobieren, die Sie über das Lenken erwähnt haben. Vielen Dank!
Pogo