AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Mini-Flugzeugsimulator

Ein Thema von Crocotronic · begonnen am 24. Mär 2015 · letzter Beitrag vom 25. Mär 2015
Antwort Antwort
Seite 1 von 2  1 2      
Crocotronic

Registriert seit: 9. Mai 2013
258 Beiträge
 
#1

Mini-Flugzeugsimulator

  Alt 24. Mär 2015, 19:26
Hallo zusammen,

nur aus reinem Interesse oder vielleicht auch im Hinblick auf die Entwicklung eines kleinen Spiels möchte ich ein "Flugzeugsimulator" bauen.
Das hört sich jetzt nach einem ganzschönen Brocken an, er soll aber wirklich nur aufs Mindeste reduziert werden, dh.
- ein einfacher Button soll als Flugobjekt dienen
- mit Key-Up und Key-Down soll die Beschleunigung geändert werden
- die Masse des Fliegers soll berücksichtigt werden, also auch die Trägheit beim Beschleunigen
- wenn der Flieger sich in einem zu steilen Winkel befindet, soll eine Art Strömungsabriss stattfinden, der durch senken der Nase wieder behoben werden kann

Jetzt ist da eine Menge Physik drin, was mir hierbei etwas Schwierigkeiten bereitet. Mein Ansatz:

Delphi-Quellcode:
var Ticker, Winkel, Beschl: Double;

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
begin
 Ticker:= 0;
 Winkel:= 0;
 Beschl:= 0;
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
begin
  if Key = 37 then
    Winkel:= Winkel + 0.1;

  if Key = 39 then
    Winkel:= Winkel - 0.1;

  if Key = 38 then
    Beschl:= Beschl + 1;

  if Key = 40 then
    Beschl:= Beschl - 1;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  v,h,a,t,s,g,w: Double;
begin
  Inc(Ticker); // 1 ms Takt
  if Ticker > 50 then
    Ticker:= 50; // Geschwindigkeit limitieren

  a:= Beschl; // Beschleunigung
  t:= Ticker/100; // Takt auf gewünschte Zeit bringen
  w:= Winkel; // Winkel e
  g:= 9.81; // Gewichtskraft

  s:= 0.5*a*Power(t,2); // 1/2 * a * t^2

  //v:= t/a;
  //h:= (v*t*w)-((g*power(t,2)/2));

  h:= (w * 0.5 * g * Power(t,2)) / 2; // sin(a) * 1/2 * g * t^2

  Button1.Position.X:= Button1.Position.X+s;
  Button1.Position.Y:= Button1.Position.Y-h;
end;
Wie ihr seht, ist das alles sehr primitiv und sicherlich nicht ganz korrekt. Es gibt hier wahrscheinlich eine Menge von Physikern unter euch, die auf den ersten Blick etliche Fehler sehen. Meint ihr, ihr könnt mir erklären (vllt. auch anhand von Code), wie die oben genannten Punkte hier noch eingefriemelt werden können?
Wenn die Theorie stimmt, werde ich aus dem ganzen Kram natürlich eine objektorientierte Lösung erstellen. Es geht mir lediglich darum, dass ich die physikalischen Gesetze hier richtig in Verbindung bringe.

Würde mich sehr freuen, wenn ihr mir ein paar Ratschläge geben könntet.

Viele Grüße
Croco

Geändert von Crocotronic (24. Mär 2015 um 21:18 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

AW: Mini-Flugzeugsimulator

  Alt 24. Mär 2015, 21:57
Ein Ratschlag gleich vor weg: Pack das ganze in eine Klasse, sonst blickst du selbst nicht mehr durch deinen Code durch. Zurückgeben tut die Klasse dann wie sich das Objekt im nächsten Zeitabschnitt bewegen muss. Damit kannst du dann alles bewegen: Panel, Shape, beliebiges grafisches Objekt.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#3

AW: Mini-Flugzeugsimulator

  Alt 24. Mär 2015, 22:55
Also erstmal sieh das mit dem Ticker sehr komisch aus. Hast du schonmal sowas gemacht, wo du numerisch integriert hast?

normalerweise misst man, wie viel Zeit seit dem letzten Frame vergangen ist. Und diese gemessene Zeit geht dann in die Berechnung ein. Die Darstellung ist dann nur wenig davon abhängig, wie schnell der PC rechnen kann.

Zur Physik: Wie ist die Ansicht? Ich nehme mal an, das Flugzeug fliegt nach rechts und man schaut von der Seite drauf?

Dann hat den Flugzeug drei Freiheitsgrade: X, Y, Theta. (Auch Nickwinkel)

Der aktuelle Zustand deines Flugzeugs enthält aber zudem die Ableitungen (alle drei) und den aktuellen Schub. Und zur Vereinfachung auch noch dessen Ableitung. (Für alles brauchst du Variablen)
Das Grundlegenden Schema sieht nun so aus:
  1. Startwerte festlegen (wo ist das Flugzeug, und wie schnell?)
  2. Ableitungen berechnen
  3. Zustände entsprechend der Ableitungen ändern (Integration)
  4. Weiter mit Punkt 2

Ich vermute mal, das Aufstellen der mathematischen Gleichungen ist noch etwas zu hoch für dich (???) daher hier eine Kurzversion (morgen vll. ausführlicher). Die Ableitungen stelle ich mit ' dar, x'' ist also die zweite Ableitung von x. (Zweimal integrieren, und dann kommt x heraus!)

x'' = Luftreibung + Antrieb = (-2*x' + Schub * cos(theta))/Masse
y'' = Luftreibung + Antrieb + Gravitation + Auftrieb = (-2*y' + Schub * sin(theta) - G + Auftrieb)/Masse
theta'' = 0;

Schub' = <Je nach Tastendruck -1, 1 oder 0>
x' = x' + dT * x''
y' = y' + dT * y''
theta' = 0.2*(arctan2(y', x') - theta) + <Je nach Tastendruck -1, 1 oder 0> // Das sollte bewirken, dass sich das Flugzeug ein bisschen "von selbst" ausrichtet

So in etwa. Vermutlich habe ich da aber noch was vergessen ... sollte schlafen gehen - morgen mehr. Gute Nacht
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

AW: Mini-Flugzeugsimulator

  Alt 25. Mär 2015, 00:01
Uff. Wenn du den Luftwiderstand noch berücksichtigen willst, dann wird es kompliziert. Denn dann hast du mit Differenzialgleichungen zu tun. Wenn ich mich recht an mein Bauingenieurstudium und der Mechanikvorlesung aus dem dritten Semester erinnere.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Mini-Flugzeugsimulator

  Alt 25. Mär 2015, 00:26
Um das Ganze zu vereinfachen erstellt man sich ein festes Zeitraster für das man die eigentlichen Berechnungen durchführt. Dadurch können einige Werte vorberechnet oder fest vorgegeben werden und meistens sind es dann simple Additionen für die Berechnung der neuen Positionswerte.

Vor jedem Zeichnen bestimmt man die Zeit die seit dem letzten Zeichnen vergangen ist und bestimmt daraus die Anzahl der Zeitraster (x). Nun werden die Berechnungen einfach (x) mal durchgeführt und dann wird dieser Zustand gezeichnet. Die noch verbleibende Restzeit wird bei dem nächsten Durchgang berücksichtigt.

Nehmen wir an, das Zeitraster legen wir auf 20ms fest und ca. alle 40-60ms können wir neu zeichnen:
Code:
ZeitRaster = 20
// erster Durchgang
ZeitReserve = 0
ZeitVergangen = 45
Frames = ( ZeitReserve + ZeitVergangen ) div ZeitRaster = 2
ZeitReserve = ZeitReserve + ZeitVergangen - Frames * ZeitRaster = 5
// 2x Frames berechnen und anzeigen

// zweiter Durchgang
ZeitVergangen = 58
Frames = ( ZeitReserve + ZeitVergangen ) div ZeitRaster = 3
ZeitReserve = ZeitReserve + ZeitVergangen - Frames * ZeitRaster = 2
// 3x Frames berechnen und anzeigen

...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Crocotronic

Registriert seit: 9. Mai 2013
258 Beiträge
 
#6

AW: Mini-Flugzeugsimulator

  Alt 25. Mär 2015, 00:38
Zuerst mal vielen, vielen Dank jfHeins!
Also die Darstellung geschieht in 2D, d.h. die Kameraposition ist erstmal ganz normal von der Seite, wie in guten alten Zeiten. Das Flugzeug soll sich auf einer Karte frei bewegen können.

Was die Begrifflichkeiten angeht: Habe gestern mein Mahte-Abitur auf dem beruflichen Gymnasium mit dem Profilfach Informatik absolviert, von dem her sollten mir Ableitung und co. bekannt sein

Grundlegend geht es mir erstmal drum, wie die Formel aussehen muss, wenn ein Flieger mit der Masse M im Winkel von z.B. 80° nach oben fliegt. Physik war noch nie meine Stärke, weshalb ich auch Chemie gewählt habe. Deshalb ist mir nicht ganz klar, wie ich die Gegenkraft mit einberechnen muss (Trägheit etc.) Außerdem soll der Flieger auch anders reagieren, wenn er nach unten Fliegt, da dann die Gewichtskraft die Beschleunigung "verstärkt".
Der Nickwinkel kann durch die Pfeiltasten variiert werden. Was du so geheimnisvoll mit Ableitung ausdrücken wolltest, ist wahrscheinlich
Code:
s'(t) = v(t)
und
Code:
s''(t) = a(t)
Nur wofür sollte ich die unbedingt bestimmen?
Das mit dem Luftwiderstand sieht zwar sehr interessant aus, ist jedoch etwas zu umfassend für mein Vorhaben. Dennoch glaube ich, dass du mir einiges erklären und mich weiter bringen könntest!

@Oliver: Vielen Dank für die Erläuterung. Da ich mich mit dem Thema "Video-Spiele" noch nie beschäftigt habe, ist soetwas sehr hilfreich für mich!

Geändert von Crocotronic (25. Mär 2015 um 00:41 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#7

AW: Mini-Flugzeugsimulator

  Alt 25. Mär 2015, 02:27
normalerweise misst man, wie viel Zeit seit dem letzten Frame vergangen ist. Und diese gemessene Zeit geht dann in die Berechnung ein. Die Darstellung ist dann nur wenig davon abhängig, wie schnell der PC rechnen kann.
Nicht nur wie schnell der PC ist ... auch TTimer wird niemals die gewollte Auflösung von 1ms hinbekommen
und da nebenbei auch noch andere Programme und das eigene Programm die Ausführng des Timerevents verzägern können, wird es je nach CPU-Auslastung noch "schlimmer".

Einfach mal ausprobieren und sich freuen, wie schon ohne viel Code der Timer (Count links) der echten Zeit (rechts) hinterherläuft.
Delphi-Quellcode:
var
  Count, Start: Cardinal;

procedure TForm3.FormCreate(Sender: TObject);
begin
  Start := GetTickCount;
end;

procedure TForm3.Timer1Timer(Sender: TObject);
begin
  Inc(Count);
  Caption := Format('%d %d', [Count, GetTickCount - Start]);
end;
bzw. (z.B. für FMX)
Delphi-Quellcode:
var
  Count: Cardinal;
  Start: TDateTime;

procedure TForm3.FormCreate(Sender: TObject);
begin
  Start := Now;
end;

procedure TForm3.Timer1Timer(Sender: TObject);
begin
  Inc(Count);
  Caption := Format('%.0n %.0n', [Count/1, MilliSecondSpan(Now, Start)]);
end;
PS: Wert2 durch Wert1 = das, was dein PC gerade jetzt für ein Timer1.Interval "wirklich" hinbekommt.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (25. Mär 2015 um 02:30 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.143 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Mini-Flugzeugsimulator

  Alt 25. Mär 2015, 10:58
...wenn ein Flieger mit der Masse M im Winkel von z.B. 80° nach oben fliegt. Physik war noch nie meine Stärke...
Keine Tragfläche bietet bei 80° Auftrieb... Das geht nur über Antriebsleistung.

Eine Tragfläche erzeuge je nach Anstellwinkel mehr oder weniger Auftrieb. Ausgehend vom Horizontalflug wo der
Auftrieb=Masse ist, kannst Du also den Anstellwinkel vergrößern und so mehr Auftrieb erzeugen...
Dadurch erhöht sich aber der Widerstand.

Dem sind jedoch Grenzen gesetzt. Wenn die Umströmende Luft aufgrund des zu hohen Anstellwinkels nicht mehr anliegt, erzeuge die Tragfläche ganz plötzlich keinen Auftrieb mehr. Das ist je nach Tragflächenprofil unterschiedlich
und ob Klappen "gesetzt" sind oder "Vorflügel"...

Mavarik
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.143 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: Mini-Flugzeugsimulator

  Alt 25. Mär 2015, 11:10
normalerweise misst man, wie viel Zeit seit dem letzten Frame vergangen ist. Und diese gemessene Zeit geht dann in die Berechnung ein. Die Darstellung ist dann nur wenig davon abhängig, wie schnell der PC rechnen kann.
Nicht nur wie schnell der PC ist ... auch TTimer wird niemals die gewollte Auflösung von 1ms hinbekommen
1ms macht ja sowieso keinen Sinn.. weil 1000 Frames geht eh nicht...

So lange meine Berechnung und der Grafikaufbau schneller sind als 16,6 ms ist alle schick... Dann komme ich auf die 60 Frames die i.d.R. die heutiges Monitore machen... Schneller lohnt nicht...
  Mit Zitat antworten Zitat
Caps

Registriert seit: 23. Mär 2006
Ort: Leipzig
299 Beiträge
 
#10

AW: Mini-Flugzeugsimulator

  Alt 25. Mär 2015, 11:17
Das mit dem Messen der Zeit, die seit dem letzten Frame vergangen ist, geht nur, wenn die Funktion der Flugbahn bekannt ist. Denn diese Funktion muss man dann integrieren. Das ist aber wohl selten der Fall. Ich würde es umgekehrt machen:

- in der Schleife die Werte korrekt berechnen (Ort, Geschwindigkeit, Beschleunigung)
- das Bild rendern; wenn die GraKa/ Prozessor nicht schnell genug ist -> Frame verwerfen

Auf diese Weise "hackt" das Bild genau wie im anderen Fall, aber die Flugbahn ist wenigstens korrekt.

lg Caps
"Der Mode cmCFS8 ist prohibitär und von mir entwickelt."
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz