Ergebnis 1 bis 11 von 11

Thema: [Hilfe] Sprungmechanik mit fixer Höhe

  1. #1

    [Hilfe] Sprungmechanik mit fixer Höhe

    Ich stehe auf dem Schlauch. Meine Sprungmechanik soll mit einer festen Sprunghöhe arbeiten und Gravitation. Heißt, meine Spielfigur soll bspw. immer 48 Pixel hoch springen, bevor die Gravitation sie runterzieht.
    Dafür brauche ich einen Algorithmus, der die Gravitation von der Sprunghöhe abhängig macht. Ich stelle mir das so vor:
    • Sprunghöhe = 48 Pixel
    • Spieler drückt Sprungtaste
    • Spielfigur springt, Bewegung auf der y-Achse nach oben
    • Gravitation beeinflusst Bewegung
    • Bewegung wird genau dann 0, wenn Sprunghöhe = 48 erreicht ist
    • Spielfigur fällt, Bewegung auf der y-Achse nach unten

    Der Algorithmus muss natürlich dynamisch sein. Gebe ich demnach 32 Pixel (beliebige Zahl) als Sprunghöhe an, muss der Übergang von Sprung zu Fall genau auf der Höhe stattfinden.

    Super Mario World arbeitet auch so. Die Sprunghöhe ist zwar abhängig davon, wie lange man die Sprungtaste gedrückt hält, variiert aber nur in Stufen, die dem Tileraster entsprechen. Kurz gedrückt halten: 16(?) Pixel hoch. Länger gedrückt halten: 32(?) hoch. Lange gedrückt halten: 48(?) hoch.

    Ich benutze den Game Maker, aber das ist eigentlich egal. Mehr als einen Schubser in die richtige Richtung brauche ich nicht.

  2. #2
    Ich glaube(!), ich habe mein Anliegen auf ein mathematisches Problem heruntergebrochen:
    x = 0
    y = 48
    z = 60
    x ist der Startwert (zu Beginn immer 0), y (hier 48) der Zielwert. x soll in z (hier 60) Additionsschritten zu y werden, wobei der Wert, der mit x addiert wird, mit jedem Schritt kleiner wird. Beim ersten Schritt ist er also am größten, beim letzten am kleinsten.

    Um das anschaulicher zu machen (die Zahlen, mit denen ich x addiere, sind hier vollkommen willkürlich):
    x = 0
    1. Addition: x + 4
    2. Addition: x + 3,9
    3. Addition: x + 3,8
    ...
    60. Addition: x + 0,1
    x = y = 48

    Es gilt eine Formel zu finden, die diese Additionsschritte berechnet. Die Formel muss allgemein sein. y kann 48 sein oder 1337 und z kann 60 sein oder 4711. Bestimmt gibt es so eine Formel. Und falls ich einen Denkfehler habe: Einfach "hier" schreien.

  3. #3
    Im Prinzip geht es doch nur um die Berechnung eines senkrechten Wurfes, oder? Für dessen Steigen und Fallen gibt es eine Formel:

    h(t) = v*t - (g/2)*t^2

    Die Anfangsgeschwindigkeit v gibst du durch deine Sprunghöhe h_max (dein y, z.B. 48) vor, denn beide hängen über h_max = (v^2)/(2g) zusammen.
    Mit der Anzahl deiner Schritte (dein z, z.B. 60) kannst du die Steigzeit in Zeitschritte zerlegen. Steigzeit t_s = v/g.
    => Zeitschritte dT = t_s/z

    Die von dir gesuchten Additionsschritte erhälst du als Differenz der Höhe zweier aufeinanderfolgender Zeitschritte:
    Additionsschritt #i = h( i*dT ) - h( (i-1)*dT ) ; i von 1 bis z

    Natürlich könntest du mit h(t) auch gleich die Höhe nach jedem Zeitschritt berechnen und hast damit direkt dein x, ohne zusätzliche Addition.

    Das wäre mMn die streng mathematische Lösung deines Problems. Geht aber vermutlich einfacher.

  4. #4
    Uff, senkrechter Wurf, das klingt gut, aber ich komm nicht drauf. :/

    Angenommen, ich will h(t) berechnen, wenn v = 5 gilt und g = 1. Dann ist h(t) = 12,5.

    In meiner bisherigen Sprungmechanik läuft das aber so:
    v = 5, g = 1, y = 0
    1. Schritt: y + v = 5;
    v = v - g = 4
    2. Schritt: y + v = 9;
    v = v - g = 3
    3. Schritt: y + v = 12;
    v = v - g = 2
    4. Schritt: y + v = 14;
    v = v - g = 1
    5. Schritt: y + v = 15;
    v = v - g = 0
    Ab dem nächsten Schritt ist v negativ und der Fall beginnt.

    Ich hätte erwartet, dass h(t) dasselbe Ergebnis, also 15 ausspucken muss. Leider bin ich ein Physik-Banause. Zwar finde ich das interessant, aber ohne eine konkrete Beispielrechnung komme ich wohl nicht weit. Und ganz überzeugt bin ich von meinem Ansatz nicht mehr, weil g ja eigentlich unveränderlich ist, meine Additionsschritte aber effektiv ein sich stets veränderndes g darstellen. Ob die Sprungbewegung damit noch natürlich aussähe?

    Danke für deinen Anstoß.

  5. #5
    Du hast schon recht, g ist eine feste Zahl (die Fallbeschleunigung und im realen Leben ca. 9,81 m/s^2), aber dadurch, dass sie mit dem Quadrat der Zeit multipliziert wird, ändert sich die Schrittweite (und da vor dem g-Term ein Minus steht, wird er wirklich kleiner).

    Hier mal das vereinfachte Ergebnis von h( i*dT ) - h( (i-1)*dT )

    = v*dT + (g/2)*(dT)^2 - g*(dT)^2*i

    Die ersten beiden Terme liefern immer das gleiche Ergebnis, denn v, g & dT sind alle fest vorgegeben (wie gesagt, durch die gewünschte Sprunghöhe, Steigzeit und Anzahl der Zeitschritte).
    Lediglich der letzte Term ist davon abhängig, der wievielte Zeitschritt (das i) es ist. Und dieser Term hat ein Minus davor, d.h. mit jedem Zeitschritt wird dein Additionsschritt kleiner.

    Mit deinen Beispielwerten (v=5, g=1) und einem Beispielzeitschritt von dT=1 sähe das Ganze so aus:

    5 + (1/2) - i = 5,5 - i

    Du siehst, der Additionsschritt wird tatsächlich mit zunehmendem i (gleichmäßig) kleiner, bis er Null rreicht bzw. negativ wird (hier ginge es von +0,5 bei i=5 direkt zu -0,5 bei i=6, da die Zahlen nicht so abgestimmt wurden, dass Null exakt erreicht wird).

    Du versuchst den Additionsschritt rekursiv (aus dem vorigen Additionsschritt) zu berechnen. v = v - g ist dafür korrekt, aber der Startwert ist falsch.
    Der erste Additionschritt ist nicht v, sondern v - g/2. Damit ergäbe sich
    v = 5, g = 1, y = 0
    => Anfangs-v = v - g/2 = 4,5
    1. Schritt: y + v = 4,5;
    v = v - g = 3,5
    2. Schritt: y + v = 8;
    v = v - g = 2,5
    3. Schritt: y + v = 10,5;
    v = v - g = 1,5
    4. Schritt: y + v = 12;
    v = v - g = 0,5
    5. Schritt: y + v = 12,5;

    Passt! (der nächste Schritt wäre negativ und die Figur beginnt zu fallen)

    EDIT: Vorsichtshalber noch eine Anmerkung. Für Sprünge aus großer Höhe solltest du die Fallgeschwindigkeit begrenzen. Das gilt immerhin in der Realität (Luftreibung) und den mir bekannten Spielen (Mario). D.h. sobald dein Additionsschritt einen gewissen negativen Wert (z.B. -10) erreicht bzw. überschreitet, ändern sich die weiteren Additionsschritte nicht mehr und die Höhe nimmt gleichmäßig ab (z.B. y = 50 -> 40 -> 30 usw.).

    Geändert von Ark_X (29.01.2016 um 13:07 Uhr)

  6. #6
    Das ist einleuchtend, danke. Jetzt bin ich aber auf mein Hauptproblem zurückgeworfen: Was, wenn ich eine beliebige Maximalhöhe y erreichen will? Dann reicht es nicht aus, wenn sich in jedem Additionsschritt v um g verkleinert, weil y erreicht wird, lange bevor v gegen 0 tendiert.

    Ich habe für y mal 15 eingesetzt und nach g aufgelöst:
    5 * 5 - (g/2)*5^2 = 15
    ...
    g = 0,8
    Die Schrittfolge sähe dann so aus:
    1. Schritt: v = v - g/2 = 4,6
    y = 4,6
    2. Schritt: v = v - g = 3,8
    y = 8,4
    3. Schritt: v = v - g = 3
    y = 11,4
    4. Schritt: v = v - g = 2,2
    y = 13,6
    5. Schritt: v = v - g = 1,4
    y = 15
    y ist also erreicht, aber v noch deutlich über g. Wenn ich v jetzt ins Negative verkehren würde, sähe das im Spiel abgehackt aus.

    Alternativ könnte ich auch g lassen und nach v auflösen:
    v * 5 - (1/2)*5^2 = 15
    ...
    v = 5,5
    Damit würde die Schrittreihenfolge wieder passen. Nur was, wenn ich ganz andere Werte einsetze?
    t = 60, g = 1, y = 48 (übersetzt: bei 60 fps soll mit einer Gravitation von 1 eine maximale Höhe von 48 Pixeln erreicht werden)
    Nach v aufgelöst:
    ...
    v = 30,8
    Das kann ja nicht stimmen, denn schon im 2. Schritt wäre y übertroffen. Ich verhaspele mich damit, die abstrakte Mathematik zu verstehen und kriege das nicht mehr in Einklang mit meinem konkreten Problem. Ist das überhaupt praktikabel?

    Die Fallgeschwindigkeit habe ich momentan stumpf auf 10 begrenzt.

  7. #7
    Zitat Zitat von Owly Beitrag anzeigen
    Das ist einleuchtend, danke. Jetzt bin ich aber auf mein Hauptproblem zurückgeworfen: Was, wenn ich eine beliebige Maximalhöhe y erreichen will? Dann reicht es nicht aus, wenn sich in jedem Additionsschritt v um g verkleinert, weil y erreicht wird, lange bevor v gegen 0 tendiert.
    Doch, das sollte eigentlich schon passen, denn g ist (zumindest real) für alle Sprünge gleich, egal wie hoch. Aber wenn du eine zu erreichende Sprunghöhe y (bzw. h_max) vorgibst, ändert sich die nötige Anfangsgeschwindigkeit

    y = (v^2)/(2g) => v = sqrt(2g*y) [sqrt = Quadratwurzel]

    Kann erst später ausführlicher werden, aber nur soviel schon mal noch zur Klärung: Ich sehe bei dir noch den Denkfehler, dass du g, y und die Dauer des Sprunges vorgeben willst. Es reichen aber schon 2 Werte vollkommen aus (z.B. Sprunghöhe und Sprungdauer). g und v ergeben sich dann daraus.
    Das g verwendest du dann auch für alle anderen Sprunghöhen und passt nur noch v an. Die Sprungzeit ergibt sich dabei dann von allein.



    Die Additionsschritte für jeden Sprung berechnest du dann wie oben beschrieben:
    Startwert: v - g/2
    jeder weitere Schritt: v = v - g


    Die durchzuführenden Schritte im bzw. vor dem Spiel dürften dann etwa so aussehen:
    Vorbereitung/Planung
    0.(da vor dem Spiel) Durch einen Referenzsprung (gewünschte Höhe y und Dauer t) den Wert für g festlegen => g = 2y/(t^2)

    Der eigentliche Sprung
    1.) Bei einem Sprung im Spiel aus der (bereits zu Beginn feststehenden?) Sprunghöhe y die Anfangsgeschwindigkeit v ermitteln => v = sqrt(2g*y)
    2.) Durchführung des Sprunges durch Berechnung der Additionsschritte für den Höhenzuwachs, beginnend mit v = v - g/2, danach immer v = v - g
    und zwischendurch jedes Mal die neue Höhe durch y = y + v berechnen.
    3.) Solange wiederholen, bis die Figur wieder festen Boden erreicht hat.

    Geändert von Ark_X (29.01.2016 um 19:32 Uhr)

  8. #8
    Zitat Zitat von Ark_X
    Ich sehe bei dir noch den Denkfehler, dass du g, y und die Dauer des Sprunges vorgeben willst. Es reichen aber schon 2 Werte vollkommen aus (z.B. Sprunghöhe und Sprungdauer).
    Stimmt, deshalb hat mein Gehirn blockiert, wenn ich mir die Lösung bildhaft vorstellen wollte.
    Mit der Berechnung von g und v aus y und t funktioniert die Mechanik perfekt. Ganz großen Dank dafür. Sie funktioniert so perfekt, dass ich mich frage, warum ich noch keinen Code gesehen habe, der das genauso handhabt. Damit hat man als Entwickler nämlich viel mehr Kontrolle, statt v und g vorzugeben und y daraus abzuleiten.

  9. #9
    Schön, wenn ich helfen konnte! Klappt es auch wirklich mit der unterschiedlichen Sprunghöhe? Denn nach meiner Vorstellung setzen die von mir beschriebenen Formeln voraus, dass die Endhöhe im Moment des Absprungs bekannt ist (also quasi sofort, wenn man den Sprungknopf drückt), doch bei Mario & Co. richtet es sich ja danach, wie lange man den Sprungknopf gedrückt hält. Für diese Phase müsste man dann eigentlich "blind" eine Steiggeschwindigkeit vorgeben und diese anpassen, sobald der Knopf losgelassen wurde und endlich sicher ist, welche Höhe erreicht werden soll.
    Aber falls das kein Problem ist, umso besser!

  10. #10
    Man könnte es doch einfach so machen, das der Sprung mit einer festen Geschwindigkeit beginnt und diese Geschwindigkeit so lange beibehalten wird, bis der Knopf losgelassen wird bzw. bis eine bestimmte maximale Höhe erreicht wurde (man soll ja nicht ewig hoch springen können).
    Und erst ab dem Punkt setzt die Formel oben ein mit 48 Pixeln (oder was es dann sein sollen) und einer Geringer werdenden Geschwindigkeit.
    Die Startgeschwindigkeit kann man ja auch in Abhängigkeit mit den Parametern aus der Formel oben setzen.

  11. #11
    Zitat Zitat von Ark_X
    Aber falls das kein Problem ist, umso besser!
    Nein, die Sprunghöhe ist fix, das passt also, wie es ist. Ich sitze an einem Beat'em Up und da ist es normal, keine variable Höhe zu haben.
    Mario ist ein Sonderfall, den ich mir bei Gelegenheit mal vorknöpfen werde. Ich habe schon viele Engines gesehen, die behaupten, Super Mario World abzubilden und keine tut es tatsächlich.

    @Eddy: Wenn ich deinen Ansatz richtig verstehe, würde ich den auch verfolgen. Marios potenzielle Sprunghöhe ist gestaffelt und je nachdem, wie lange man den Knopf gedrückt hält, müsste eine andere Maximalhöhe vorgegeben sein, die in Abhängigkeit zur schon erreichten Höhe stünde.

    Edit:
    Hm, nee, die Sprunghöhe in SMW ist doch ganz variabel, ist nur an der Spitze exakt vier Tiles (16x16) hoch.

    Geändert von Owly (31.01.2016 um 19:17 Uhr)

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •