Kochbuch: Ein Schienenfahrzeug bewegen - Minimal-Script

Aus LOTUS Wiki DE
Version vom 23. Oktober 2023, 22:03 Uhr von DrBlackError (Diskussion | Beiträge) (1 Version importiert: Init)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

In diesem Artikel erfahrt Ihr, was Euer frisch importiertes Schienenfahrzeug mindestens können muss, um sich über eine Karte zu bewegen. Voraussetzung für dieses Script ist, dass Ihr für Euer Fahrzeug zwei Drehgestelle mit je zwei Achsen definiert habt. Wie das geht, erfahrt Ihr hier.

Das vollständige Script, bereit zum Import, ist an diesen Artikel angehängt. Just use it!

Im Folgenden gehen wir durch die einzelnen Abschnitte durch, um hoffentlich nachhaltig für Verständnis zu sorgen.

{PUBLIC_VARS
  M_Axle_N_0_0: single;
  M_Axle_N_0_1: single;
  M_Axle_N_1_0: single;
  M_Axle_N_1_1: single;
  
  MBrake_Axle_N_0_0: single;
  MBrake_Axle_N_0_1: single;
  MBrake_Axle_N_1_0: single;
  MBrake_Axle_N_1_1: single; 
}
{PUBLIC_BUTTONS
  Throttle;
  Brake;
  MaxBrake;
}

Gemäß diesem Artikel über die Grundlagen unseres Script-Systems, ist der erste Abschnitt für die Deklaration der Variablen und Buttons bestimmt. LOTUS verlässt sich darauf, dass das Fahrzeug die hier definierten Anzahlen an Drehgestellen und Achsen auch besitzt. Hier wird erklärt, wie genau die beiden Variablen-Arten funktionieren und welchen Wertebereich sie unterstützen. Die erste Ziffer markiert grundsätzlich den Index des Drehgestells, die zweite Ziffer die der Achse des Drehgestells, jeweils 0-basiert.

Wir haben also die Traktionskraft und die Bremskraft - jeweils für die Drehgestelle mit dem Index 0 und 1 an deren jeweiligen Achsen mit dem Index 0 und 1.

Des Weiteren wurden diesem Artikel die standardisierten Buttons entnommen, mit denen das Fahrzeug angesprochen werden kann. Für unser Vorhaben reichen die Buttons für Gas, Bremse und Notbremse.

var
  _throttle: boolean;
  _brake: boolean;
  _maxbrake: boolean;

Es folgt der Bereich der lokalen, also für das nachfolgende Script gültigen, Variablen. Diese Variablen folgen keinen LOTUS-weiten Konventionen, sondern vielleicht den Konventionen für wartungsarmen Code oder welcher Religion Ihr folgt. Ich habe hier einen Unterstrich hinzugefügt, um diese Variablennamen optisch von den Public Buttons abzugrenzen. Der Unterstrich ist nicht konventionell!

Wir benötigen diese drei Variablen vom Typ boolean (eine Variable, die die Zustände WAHR und FALSCH bzw. TRUE und FALSE) annehmen kann, um script-weit Handlungen vorzunehmen, die von diesen drei Zustands-Variablen abhängen.

Mit der Deklaration an dieser Stelle sind die Variablen dem gesamten Script bekannt, aber nicht darüber hinaus. Eine Verwendung beispielsweise in der Fahrzeug-Konfiguration (um Texturen, Meshs oder Animationen mit ihnen zu steuern) ist nicht möglich.

procedure SimStep;
var
  throttleforce: single;
  brakeforce: single;
begin
  if _throttle then
  begin
    throttleforce := 40000; 
  end
  else if _brake then
  begin
    throttleforce := -40000;
  end
  else
  begin
    throttleforce := 0;
  end;
    
  if _maxbrake then
    brakeforce := 100000
  else
    brakeforce := 0;
  
  M_Axle_N_0_0 := throttleforce;  
  M_Axle_N_0_1 := M_Axle_N_0_0;
  M_Axle_N_1_0 := M_Axle_N_0_0;
  M_Axle_N_1_1 := M_Axle_N_0_0;
  
  MBrake_Axle_N_0_0 := brakeforce;  
  MBrake_Axle_N_0_1 := MBrake_Axle_N_0_0;
  MBrake_Axle_N_1_0 := MBrake_Axle_N_0_0;
  MBrake_Axle_N_1_1 := MBrake_Axle_N_0_0;
end;

Eine procedure mit diesem Namen wird grundsätzlich von LOTUS selbst aufgerufen, nämlich einmal pro Frame. Die genaue Funktionsweise dieser procedure ist hier erklärt. Grob gesagt, soll in dieser procedure die Verarbeitung stattfinden. Hier werden Vorgänge angestoßen und durchgeführt.

Auch hier findet sich an erster Stelle wieder eine Variablen-Deklaration. Hier deklarierte Variablen sind ausschließlich für die zugehörige procedure nutzbar, nicht darüber hinaus. Wir ermitteln hier anhand bestimmter Bedingungen, welche Kräfte auf die erwähnten Drehgestell-Achsen wirken. Da dies ein sehr simples Script sein soll, sind die wirkenden Kräfte einfach nur vom Zustand der im vorigen Schritt deklarierten Variablen abhängig. Für die Traktionskraft throttleforce 40000 (Newton) im Falle von _throttle, also beim Gasgeben, -40000 beim Bremsen _brake oder 0, wenn nichts dergleichen passiert. Die Traktionskraft ist positiv in Normalrichtung und negativ in entgegengesetzter Richtung, eben beim Bremsen und Rückwärtsfahren.

Im Falle der Notbremse _maxbrake wird die Bremskraft brakeforce genutzt. Jetzt nicht verwirren lassen: Die Bremskraft wirkt grundsätzlich schon in die entgegengesetzte Richtung der Traktionskraft, daher muss diese NICHT negativ sein, sondern darf nur positiv sein!

Von oben nach unten die Zeilen erklärt und übersetzt:

  • Falls _Gasgeben dann
  • Traktionskraft := 40000
  • sonst falls _Bremsen dann
  • Traktionskraft := -40000
  • ansonsten
  • Traktionskraft := 0;
  • Falls _Notbremse dann
  • Bremskraft := 100000
  • sonst
  • Bremskraft := 0;

Anschließend werden die auf diese Weise ermittelten Kräfte noch den von LOTUS erwarteten Public Variablen zugewiesen. Da wir zwei Kräfte an jeweils zwei Drehgestellen mit jeweils zwei Achsen haben, müssen wir insgesamt 8 Variablen zuweisen: Die Traktionskraft für alle vier Achsen sowie die Bremskraft für alle vier Achsen.

LOTUS wird intern nach Abschluss dieser procedure die beschriebenen Variablen verarbeiten und die nötigen Schlüsse für die Physik-Engine ziehen, wie Vorwärtsbewegung, Rückwärtsbewegung oder Anhalten, Rollen, etc.

procedure OnButton(id: string; value: boolean; cockpitIndex: byte);
begin
  if (id = 'Brake') then
  begin
    _brake := value;
  end
  else if (id = 'Throttle') then
  begin
    _throttle := value
  end
  else if (id = 'MaxBrake') then
    _maxbrake := value;
end; 

Eine procedure mit diesem Namen und diesen Parametern wird ebenfalls automatisch von LOTUS aufgerufen. Die Parameter, also Variablen und Konstanten, die beim Aufruf der procedure gefüllt werden, können nur innerhalb dieser procedure benutzt werden. Zusätzlich könnten auch wieder weitere Variablen deklariert werden, die nur innerhalb der procedure verwendet werden. Das ist hier aber nicht nötig und nicht der Fall.

Wie unschwer zu entnehmen, sendet LOTUS unter dem Parameter id den Identifikator für die vom Spieler gedrückte Taste mit. Diese wurden zuvor fast ganz oben im Script unter den PUBLIC_BUTTONS deklariert. Nun wird beim Aufruf dieser procedure abgefragt, welche der drei Tasten gedrückt oder losgelassen wurde. Für den Fall, dass sie gedrückt wurden, wird der Paramter value auf wahr, also TRUE, gesetzt, beim Loslassen der Taste auf false. Für Fahrzeuge mit mehr als einem Fahrerstand wird auch der Index des Cockpits übergeben, aus dem heraus der Befehl gesendet wurde - das ist aber für unser Minimal-Script irrelevant.

An dieser Stelle steuern wir nun den Zustand der obig script-weit deklarierten Variablen. Wir wollen, dass diese Variablen den Zustand widerspiegeln, ob der Spieler gerade eine Taste drückt oder loslässt. Deshalb nehmen die obig script-weit deklarierten Variablen einfach den Zustand an, den der Spieler durch Drücken oder Loslassen einer Taste vorgibt.

Von oben nach unten die Zeilen erklärt und übersetzt:

  • Falls Taste mit id "Bremse" gesendet dann
  • _Bremsen := gedrückt oder losgelassen
  • sonst falls Taste mit id "Gas" gesendet dann
  • _Gasgeben := gedrückt oder losgelassen
  • sonst falls Taste mit id "Notbremse" gesendet dann
  • _Notbremse := gedrückt oder losgelassen;

So schließt sich der Kreis zum vorigen Abschnitt über Simstep, wo der Zustand der Variablen _Bremsen, _Gasgeben und _Notbremse abgefragt und entsprechend in die Traktionskraft und Bremskraft übersetzt und in die Achsen geschrieben werden.

end.

Auch das schönste Script muss einmal zu Ende gehen. Und das tut es hier an dieser Stelle nach getaner Arbeit mit dem Wörtchen end..