Freier Fall und schiefer Wurf in C++?
-
Hallo liebe C++ler,
Ich habe erst vor kurzem angefangen, in C++ zu programmieren, und im Moment bin ich gerade dabei, in C++ ein 2D-Spiel für das iPhone zu programmieren (und zwar mit diesem SDK: www.dragonfiresdk.com).
Ich habe jedoch einige Fragen bezüglich Geraden, Beschleunigungen und Kurven:
1. Stellt euch vor, ich habe ein 2D-Spiel und ich muss jetzt von oben eine Bombe (in Form eines .PNG-Bildes) fallen lassen. Dieses .PNG-Bild hat natürlich eine x -und eine y-Koordinate. Doch wie erkläre ich jetzt dem Compiler, dass er die Bombe ab da oben nach unten beschleunigen soll?
2. Stellt euch wieder das 2D-Spiel vor und eine weitere Bombe, die ich jetzt aber in einem bestimmten Winkel Richtung Boden "werfe". Wie einen Gummiball, den man auf einer kerzengeraden Straße mit 0° Steigung draufschmeißt. Dieser prallt dann von der Straße ab und springt wieder auf, bis er schließlich ein wenig weiter wieder auf dem Boden aufprallt, und dann wieder nach oben geht, wieder aufprallt, usw. Wie erkläre ich denn das dem Compiler?
Ich hätte mir gedacht, vlt. irgendwas mit Parabeln zu machen, doch wie stelle ich das an? (Wir vernachlässigen übrigens die Schwerkraft in dem Fall, sonst wird's zu kompliziert.)
Damit das Ganze noch ein wenig vorstellbar ist, hier eine kleine grafische Darstellung: http://img835.imageshack.us/img835/5011/geradeparabel.png
Mein Problem ist, dass ich keine zusätzlichen Engines und Librarys verwenden darf, sonst hätte ich es mit Box2D oder irgendeiner Physik-Engine schon probiert. Ich darf lediglich die C++ Standard Library verwenden. Doch Bilder darstellen und bewegen kann ich mit dem oben genannten SDK und seiner Engine schon. Es geht mir praktisch nur um die "physikalische Formel" für die oben genannten Probleme, bzw. wie ich diese in C++ umsetzen kann.
Es wäre super, wenn ihr auch Beispielcode für mich hättet, damit ich euch nicht weiter mit Fragen plage
Danke vielmals für die Benatwortung meiner Fragen.
Liebe Grüße,
Ivan.
-
Ivaaan schrieb:
Ich hätte mir gedacht, vlt. irgendwas mit Parabeln zu machen, doch wie stelle ich das an? (Wir vernachlässigen übrigens die Schwerkraft in dem Fall, sonst wird's zu kompliziert.)
Was ist daran kompliziert? Anstatt für jeden Spezialfall die Lösung von Hand auszurechnen und zu programmieren bräuchtest du nur einmal den allgemeinen Fall programmieren und der Computer berechnet die Lösung. Und gerade Schwerkraft ist total trivial weil es einfach nur eine konstante Kraft nach unten ist. Selbst die Masse kürzt sich aus den Bewegungsgleichungen raus, so dass du noch nicht einmal auf diese zu achten brauchst.
Allegemeiner Ansatz zur Lösung der Newtonschen Gleichungen im Computer ist Zeitdiskretisierung. Du teilst die Zeit in Schritte ein. Dann berechnest du in jedem Schritt die Kräfte auf deine Objekte und setzt dann deine Objekte entsprechend um. Und dann den nächsten Zeitschritt und so weiter.
Da es sich bloß um ein Spiel handelt kannst du das mit einen ganz einfachen naiven Algorithmus machen und brauchst dir keine Sorgen um Energieerhaltung, Stabilität und Genauigkeit zu machen.
edit: Und da das extrem nach Hausaufgabe riecht gebe ich dir keinen Beispielcode. Denn das Beispiel wäre schon die Lösung. Ich kann dir aber verraten, dass dein Lehrer die von mir vorgeschlagene allgemeine Lösung erwartet und nicht handcodierte Spezialfälle.
-
Hausaufgabe wäre erlich gesagt zu schön, ich wäre froh wenn wir sowas an der Schule lernen würden. Da ich aber in Tirol/Österreich wohne, fängt meine Schule erst ab 13. Sep. wieder an.
Und in Österreich zumindest hat noch jedes Bundesland schulfrei, also dass kann man mit Sicherheit ausschließen.
Ich mache also, jetzt im Parabelfall, eine Funktion y=x^2 (also in dem Fall eine stinknormale Parabel) und füge jetzt statt y und x z.B. Bomby und Bombx ein, ist das richtig? Damit habe ich die Allgemeine Form. Und die Bewegung dann mit Zeitdiskretisierung?
Und es tut mir leid wenn es wirklich nach Hausaufgabe klingt, jedoch wäre es mit Samplecode viel leichter verständlich. Solltest du an dem zweifeln, uploade ich dir gerne meinen Schülerausweis.
Aber erstmal vielen Dank für die Hilfe!
-
Hi,
mein Tipp: halte dich erstmal vom C++ Code fern, nimm dir ein Blatt Papier, zeichne dir ein Koordinatensystem da hin und berechne die Funktionen, welche die x- und y-Position deines Objektes zum Zeitpunkt t enthalten.
Dabei ist die Funktion "xpos" noch recht leicht, da wir Reibung vergessen und dann keine Kraft nach "vorne" wirkt.
xpos(t) = xPosOriginal + t * geschwindigkeitX;
Für die y-Position wird es "etwas" schwerer. Um es nicht selbst auszurechnen (a: zu lang her, b: zu faul) habe ich mir mal meine Physik-Formelsammlung von anno dazumal genommen und direkt auf Seite 1 die Formel gefunden, die notwendig ist:
s = 1/2 * g * t * t
s ist dabei der "durchfallene Weg", g der Normwert der Fallbeschleunigung ("Erdbeschleunigung"). Für deine Formel also:
ypos(t) = yPosOriginal - 1/2 * g * t * t;Fürs aufprallen brauchst du nun die Geschwindigkeit, die am Aufprallpunkt in y Richtung geherrscht hat (gleiche Seite der Formelsammlung):
v = g * t
wobei wir hier das t brauchen, bei dem ypos(t) = 0 gilt, also:
t' = sqrt(2* yPosOriginal/g), d.h.
v' = sqrt(2 * g * yPosOriginal); (Edit: bemerke grade, die Formel stand auch direkt daneben :))Beim Aufsteigen (oh, ich musste einmal umblättern) gilt dann:
s = v' * t - 1/2 * g * tt;
(ich mache hier die Annahme, dass die Bewegungsenergie komplett in die andere Richtung umgekehrt wird; ggf. willst du v' etwas dämpfen, in dem du die Aufpraller mitzählst und dann v' etwas kleiner machst, etwa 0.9v')Die Aufstiegsgeschwindigkeit ist v = v' - gt. Wenn diese 0 wird, hat deine Kugel den "Gipfel" erreicht und beginnt zu fallen, wo du dann wieder die Formel oben nutzen kannst.
Insgesamt sieht die Funktion dann so aus:
ypos(t) = {
yPosOriginal - 1/2 * g * t * t wenn im Fallen;
sqrt(2 * g * yPosOriginal) * t - 1/2 * g * tt;
}Wie gesagt: beim Programmieren ggf. Aufpraller mitzählen (oder in die Fallunterscheidung einpfriemeln) und dann v' * 0.9**(Anzahl Aufpraller) oder sowas rechnen.
-
http://c-plusplus.net/forum/viewtopic-var-t-is-23653-and-highlight-is-.html
Das hat mir damals sehr gut geholfen
-
Wow, DANKE für die großartige Hilfe!
Ich werde das jetzt alles mal probieren. Und ich glaube ich melde mich hier im Forum auch mal an, scheint ziemlich ziemlich super zu sein.
Nochmals vielen Dank! Wenn ich heute noch Zeit habe, werde ich es gleich probieren und euch gleich berichten, ob und mit welcher Methode es geklappt hat!
DANKE!