Korrekte Spielgeschwindigkeit (Framebremse)



  • @TomasRiker

    Nur damit ich das auch richtig verstanden habe 😉 😃 🙂 . Die neue errechnete Zahl wird dann mal der Bewegung gerechnet richtig ???
    Und daraus folgt für mich schon die zweite Frage, wie errechne ich die Differenz zwischen den Frames (mit welchem Counter ) ?

    Ein bißchen Code wäre echt nett 🙂 .

    MfG Unwissender



  • ...

    hast Du bei 50 FPS weniger als 1 Pixel pro Frame, nicht mehr!

    Stimmt.. hast ja Recht... Mmh. Ja das müsste ich mal ausprobieren *g*

    Aber meine unüberlegt gewählte Einheit war auch falsch 🙄
    1 pixel pro frame... Das ist ja gerade das Problem... Die bewegung
    soll unabhängig von den Frames sein... Wie wäre es also mit
    1 pixel / sekunde = 1 px/s

    Aber wie ist das mit Timern? Kennt sich da eiener aus? Das wäre ja
    noch leichter 😃

    Mal überlegen...

    **Am Anfang der Schleife hole ich einen möglichst
    genauen Millisekunden-Ticker.

    Dann lasse ich erstmal das Bild rendern und KI und sonen
    Kram erledigen.

    Jetzt rechne ich die Zeit aus, die das gedauert hat.
    Jetzige Zeit - Startzeit = Differenz

    Jetzt brauche ich den Faktor, mit dem alle Positionsänderungen
    multipliziert werden... Angenommen ich habe 20 ms Differenz...
    1000 / 20 = 50
    Aha ich habe also 50 fps. Müsste also die Geschwindigkeit meines
    Objektes mit 1/50 multiplizieren...

    Mist! Das sind ja gleich 2 Divisionen. 1 pro frame + 1 pro objekt

    Aber:
    *
    (1000/20) ^-1 = 1/50
    bzw: 20/1000 = 1/50
    *

    hehe!

    Mmmh. Ich weiss zwar nicht, ob das hilft, aber:
    20 / 1000 = 0.001 * 20 Jetzt sind alle
    Divisionen weg *g*

    So jetzt multiplizieren wir unsere geschwindigkeit in px/s
    mit dem errechneten Faktor (zb. 1/50)

    Das ergebnis wird zu einer Fließkomma-Variable mit unserer
    Position hinzuaddiert.

    Für unsere Zeichenaktionen wird das ganze dann auf bzw. abgerundet
    und fertig !!!

    **

    Wegen dem Code... Ich versuchs einfach mal: (Achtung, Pseudocode)

    long  position_x = 0;
    long  zeit;
    float unterschied;
    float position_x_rechnen = 0;
    float faktor;
    
    for(;;)
    {
        zeit = Hole_Millisekunden();
        Rendere_das_Bild();
        unterschied = Hole_Millisekunden() - zeit;
        // Beispiel für 10 px/s nach rechts...
        faktor = 0.001 * unterschied;
        position_x_rechnen += 10 * faktor;
        position_x = Runde_auf_oder_ab(position_x_rechnen);
    }
    


  • Na also, Du kannst es doch! Oder hast Du das irgendwoher kopiert?



  • Oder hast Du das irgendwoher kopiert?

    Ho ho ho!!!

    Wenn ich das irgendwo gefunden hätte, hätte ich doch nicht
    dieses Forum hier zugepostet, oder? *g*

    Trotzdem meine Fragen:

    - Stimmt der Code so?
    - Was ist mit Threads?
    - Was ist mit Timern?

    Danke...

    PS: Warum wird V_O_R_R_A_U_S eigentlich zensiert?



  • Original erstellt von Shinji Ikari:
    **Ho ho ho!!!

    Wenn ich das irgendwo gefunden hätte, hätte ich doch nicht
    dieses Forum hier zugepostet, oder? *g*

    Trotzdem meine Fragen:

    - Stimmt der Code so?
    - Was ist mit Threads?
    - Was ist mit Timern?

    Danke...

    PS: Warum wird V_O_R_R_A_U_S eigentlich zensiert?**

    Im ******* wird zensiert, weil es falsch ist. Es heißt "im Voraus".
    Also der Code sieht gut aus, ich mache es fast genauso.
    Der Windows-Timer ist zu ungenau und außerdem würde dann wahrscheinlich bei zu langsamen Szenen der Stack überlaufen oder es würde genauso langsam laufen wie normalerweise auch.
    Threads zu benutzen halte ich für übertrieben.



  • Also ich hab das mal vor kurzem Programmiert, aber mit einer Basic Sprache (BlitzBasic3D), hat prima gefunzt, hier der Pseudocode dazu:

    // erstmal die differenz zwischen den Frames bilden
    aktuelleZeit = GetCurrentTime()
    Differenz = aktuelleZeit - ZeitDesVergangenenFrame
    ZeitDesVergangenenFrame = aktuelleZeit
    // So, jetzt hast du die die Differenz gebildet, willst du jetzt ein Objekt in x richtung 30 pixel/sec fahren lassen so musst du einfach folgendes machen:

    x= x + 30*Differenz
    DrawObject(x,y)

    // Das wars. Wie du mit C++ die aktuelle Zeit herbekommst weis ich auch nicht, da ich gerade erst mit C++ angefangen hab und bei einfachen Konsolenanwendungen gerade bin (mit BlitzBasic3D war es sehr einfach, der Code sah fast so aus)....



  • Jo, BlitzBasic kenn ich. Is eigentlich ganz lustig, hab aber damit
    aufgehört...

    Ähm. Wenn du 30 px/s geschwindigkeit haben willst, und du zB. eine
    Differenz von 20 ms hast. dann bewegt sich dein Objekt nach deinem
    Code mit 30000 px/s !!!

    Naja..
    Obiges gilt natürlich nur für den Fall, dass GetCurrentTime()
    Millisekunden wiedergibt.. Wenns zB. Sekunden wiedergibt, ginge
    das ganze... aber dann müssten die Sekunden bis auf die 3te Nachkomma-
    stelle genau zurückgegeben werden... Dass eine Funktion einen Wert
    wie zB. 5,025 sek. zurückgibt kann ich mir nur schwer vorstellen...
    Was machst du denn dann, wenn die sekunden von 59 wieder auf 0
    umspringen??? wenn du in dem Moment die Differenz ausrechnest, hast
    du ein Problem *g*

    Beim Timer, wie ich ihn verwendet habe wird die Zeit wiedergegeben,
    die der PC schon an ist. und zwar in Millisekunden... Das ist IMHO
    genauer und praktischer 🙂



  • Die Zeit bekommt man z.b. mit dem XGamesSDK mit der Klasse "XTimer" ;).

    Bye, TGGC



  • Du hast schon recht, GetCurrentTime müsste sekunden widergeben, BlitzBasic3D gibt es in millisecunden wider, die funktion GetCurrentTime() rechnet bei mir halt das ganze in sekunden um, naja ob millisec. oder nur sec. ist eigentlich egal. Das mit dem Timer ist auch eine Lösung obs genauer ist, weis ich nicht, jedenfalls gibts da verschiedene wege die Zeit zu bekommen, der Lösungsansatz bleibt aber der gleiche...



  • Hi !
    Bei www.gamedev.net gibts nen netten Artikel darüber...
    Und ab ins FAQ !


Anmelden zum Antworten