S-Kurve für Geschwindigkeit definieren

  • GM 8

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • S-Kurve für Geschwindigkeit definieren

    Hallo,
    wie kann ich die Geschwindigkeit eines Objekts in einer S-Kurve ansteigen lassen? Damit meine ich, dass der Speed am Anfang langsam steigt und später immer langsamer zunimmt, bis schließlich die Höchstgeschwindigkeit erreicht wurde. Zum besseren Verständnis ein Bild:
    Google hat mir diesbezüglich leider keine (verständliche) Formel ausgespuckt und selbst drauf gekommen bin ich auch noch nicht.

    Ich hoffe, ihr könnt mir helfen.

    Grüße, Skotchy
    "Ich sollte schlafen gehen"

    ~Pika-Pika~
  • EDIT: Zu spät :D Denke das was Skotchy gepostet hat ist die bessere Methode.

    Ich weiß zwar nicht ob man das auch anders lösen kann aber ich würde das so machen:

    GML-Quellcode

    1. //Als erstes den Geschwindigkeits wert festlegen(Creation Event)
    2. var speed=1;


    GML-Quellcode

    1. //Dann denn Speed erhöhen(Step Event)
    2. speed++;


    Nun wird der Speed um 1 erhöht, wenn du nun willst das er sich aber langsamer erhöht dann machste das so:

    GML-Quellcode

    1. speed++;
    2. speed-=0.4;


    Nun wird der speed nur um 0.6 erhöht.

    Packst das dann in nen Alarm und musst es dann so einstellen, dass wenn der Alarm eine bestimmte Zeit erreicht hat der speed Wert sich um 0.1 (oder was auch immer erhöht) und ein neuer Alarm gestartet wird.

    Also wenn der Speed vorher 0.6 war dann musste das machen:

    GML-Quellcode

    1. speed++;
    2. speed-=0.3;

    Dann beträgt der Speed 0.7

    Ich denke die Grund idee ist klar und wie gesagt obs noch eine einfachere oder andere Methode gibt es zu lösen weiß ich nicht.
    Imagine taking your usual two century long nap minding your own business when suddenly some cunt wakes you up.
    You tell him to f*ck off of course but just when you finally managed to fall asleep again the same asshole comes knocking again. I'd attack that dick too.
  • @MewX:
    Die Funktionen sehen vielversprechend aus aber einiges verwirrt mich. Ich hab da mal eine rausgesucht:

    Quellcode

    1. float inOutExp(float x){
    2. if(x < 0.0f) return 0.0f;
    3. if(x > 1.0f) return 1.0f;
    4. return x < 0.5f ? 0.5f * pow(2f, 10f * (2f*x - 1f)) :
    5. 0.5f * (-pow(2f, 10f * (-2f*x + 1f)) + 2f);}

    Warum steht bei jeder Funktion auf der Seite dieser Teil im Code:

    Quellcode

    1. if(x < 0.0f) return 0.0f;
    2. if(x > 1.0f) return 1.0f;

    Was macht das Fragezeichen und der Doppelpunkt:

    Quellcode

    1. return x < 0.5f ? 0.5f * pow(2f, 10f * (2f*x - 1f)) :


    @DragonXZ:
    Ich verpacke das mal mit einer Abfrage ins Step-Event und gucke, was ich so schlimmes anstellen kann.

    Danke euch für die schnelle Antwort.

    Grüße, Skotchy
    "Ich sollte schlafen gehen"

    ~Pika-Pika~
  • @MewX Diese Seite da ist aber irgendwie nicht vollständig..
    Was er braucht sollte das "easeInOutCubic" sein. Bei den Funktionen kann ich zumindest soetwas nicht finden. Da sind auch nur 17 Funktionen gegeben während man auf der Abbildung 30 sieht.
    Oder überseh ich iwas gravierendes? o:


    @Skotchy
    if(x < 0.0f) return 0.0f;
    if(x > 1.0f) return 1.0f;
    Dies sorgt dafür dass keine Fehler auftreten wenn du einen Wert verwendest der kleiner oder größer als 0 ist. Diese Funktionen beziehen sich alle sozusagen auf Faktoren wobei der Wert 0 die Linke Seite des Schaubilds bedeutet und der Wert 1 das Rechte Ende ausgibt. Unten auf der Seite wird die Verwendung auch erklärt.

    Beim Fragezeichen bin ich überfragt... könnte was mit einer Fallunterscheidung innerhalb des statements zutun haben.
    EDIT: Nicht zu 100% sichr aber könnte sein dass diese Konstellation bedeutet: Wenn das Statement vor dem Fragezeichen true ausgibt, führe das was vor dem Doppelpunkt ist aus, sonst führe das dahinter aus. Nur eie Vermutung.

    Willst du auf diese Drachen und -eier klicken?
    Sie werden sich freuen ;)

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von DragonGamer ()

  • Stimmt, fehlen ein paar. Aber InOutExp ist eh näher dran.

    Das ? ... : ist eine Kurzform von if, die in C/C++ manchmal Verwendung findet. Bedingung : dann ? sonst.

    Wie auch im Text steht, sind diese Funktionen nur für Eingabewerte von -1 bis 1 definiert. Das hat den Vorteil, dass man recht einfach interpolieren kann, z.B. so:

    GML-Quellcode

    1. kurvenfunktion(x/maxwert)

    Dann ist maxwert dort, wo jetzt 1 ist.
  • ich hätte das ganze wahrscheinlich mit dem cosinus glöst.

    GML-Quellcode

    1. speed = 0.5*maxwert*(1-cos((pi/beschleunigungsdauer)*min(t,beschleunigungsdauer)));

    maxwert ist die maximale geschwindigkeit
    beschleunigungsdauer ist die zeit, bis die maximale geschwindigkeit ereicht ist (in steps)
    t ist die zeit (t muss am anfang der beschleunigung auf 0 gesetzt werden und dann jeden step um 1 erhöht werden)
  • Hab jetzt die Vorschläge von MewX, J@kob und Basti durchprobiert, dass ist das Ergebnis:

    MewX's Vorschlag:
    War ziemlich schwierig, für mich, den Code zu übersetzen, habe es aber mehr oder weniger geschafft:

    GML-Quellcode

    1. if (speed < 0) {speed = 0;}
    2. if (speed > top_speed) {speed = top_speed;}
    3. if (speed < top_speed / 2) {speed = (0.5 * top_speed) * power((2 * top_speed), (10 * top_speed) * ((2 * top_speed) * speed - top_speed));}
    4. else {speed = (0.5 * top_speed) * (-power((2 * top_speed), (10 * top_speed) * ((-2 * top_speed) * speed + top_speed)) + (2 * top_speed));}

    Das Ergebnis : "Error in function power().". Schade, hat ziemlich lange gedauert.

    J@kob's Vorschlag:
    Das war nicht weiter schwer zu übernehmen und funktioniert auch aber es beschleunigt mir doch etwas zu langsam während der Mittelphase (von 20% - 80% des maxspeed's).Die Mittelphase kann fast schon wie im Flug vorbeigehen(ist ja ein Raumschiff), dafür aber langsamer auf die Höchstgeschwindigkeit kommen. Was kann ich da ändern, damit das mehr meinen Vorstellungen entspricht?

    Basti's Vorschlag:
    Bin leider nicht drauf gekommen was ich für k einsetzen sollte.

    Bis hierhin danke ich euch schon einmal für eure Vorschläge.

    Ich werde jetzt noch bisschen mit dem Vorschlag von DragonXZ rumspielen.

    Grüße, Skotchy
    "Ich sollte schlafen gehen"

    ~Pika-Pika~
  • Beschleunigt fast genau so, wie ich es mir vorgestellt hatte. Danke :thumbsup: .
    Ich habe mir die logischen Funktionen auch schon angesehen, konnte mir aber keine brauchbare Formel ableiten. Wie hast du das gemacht? Das könnte mir in der Zukunft vielleicht helfen.

    Grüße, Skotchy
    "Ich sollte schlafen gehen"

    ~Pika-Pika~
  • GML-Quellcode

    1. // inOutExp(x)
    2. if (argument0 < 0) {
    3. return 0;
    4. }
    5. if (argument0 > 1) {
    6. return 1;
    7. }
    8. if (argument0 < 0.5) {
    9. return 0.5 * power(2, 10 * (2*argument0 - 1));
    10. }
    11. else {
    12. return 0.5 * (-power(2, 10 * (-2*argument0 + 1)) + 2);;
    13. }
    Alles anzeigen

    Und dann in ein Step-Event:

    GML-Quellcode

    1. x = mouse_x;
    2. y = room_height - inOutExp(x/room_width) * room_height;

    Zuerst sollte man sich bewusst machen, dass die Funktion Werte zwischen 0 und 1 annimmt (ich ging weiter oben fälschlicherweise noch von -1 bis 1 aus) und auch Werte zwischen 0 und 1 ausgibt. Entsprechend teile ich x durch die Raumbreite und multipliziere den Funktionswert mit der Raumhöhe. Da y im Game Maker in die andere Richtung wächst, habe ich ich den Funktionswert von der Raumhöhe abgezogen.
  • Warum hast du das f weggelassen? Wenn mich nicht alles täuscht, dann heißt power(2, 10) einfach nur 2 hoch 10. Ist es demnach nicht unsinnig immer wieder 2 hoch 10 zu rechnen anstatt fest 1024 einzugeben? Ich war der Meinung das f ziemlich wichtig ist/war.
    Aber danke für die Korrektur, nun funktioniert auch das gut :thumbsup: .
    "Ich sollte schlafen gehen"

    ~Pika-Pika~
  • Skotchy schrieb:

    Beschleunigt fast genau so, wie ich es mir vorgestellt hatte. Danke .
    Ich habe mir die logischen Funktionen auch schon angesehen, konnte mir aber keine brauchbare Formel ableiten. Wie hast du das gemacht? Das könnte mir in der Zukunft vielleicht helfen.

    Ich hab gar nichts gemacht.
    Bei Wikipedia stand doch die Formel dafür! :D

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Basti ()

  • Es ist ja nicht einfach 2^10, sondern 2^(10 * mehrzeug). Die 2^10 da rauszuziehen dürfte auch nicht wirklich helfen, da 2^eineganzezahl auf einem Computer sehr fix gehen sollte - immerhin rechnet er zur Basis 2. Der Code sollte schon ziemlich effizient sein, lediglich begreif ich grad nicht, warum die 0.5 nicht mit in den Exponenten gezogen wird (als -1).

    Das f ist ebenfalls ein Überbleibsel aus C/C++. Damit wird kenntlich gemacht, dass es sich um einen Float (Gleitkommazahl) handelt. Ansonsten interepretiert C/C++ diese als ganzzahlige Werte (bei z.B. 2) oder als Doubles (bei z.B. 2.0), die dann immer gecastet (konvertiert) werden müssten, wenn sie mit einem anderen Float verrechnet werden. Der Game Maker selbst arbeitet immer mit doubles (Fließkommezahlen, die soviel Speicherplatz wie zwei Floats beanspruchen) und deshalb fällt diese Kennzeichnung flach.