Bewegung eines Objektes über bestimmte Distanz in bestimmter Zeit



  • Hallo werte Forenmitglieder,

    ich habe eine eher konzeptionelle Frage. Angenommen, ich habe ein 2d-Objekt (X) und dazu einen Array (geg. Breite und Höhe), der die Objekte hält. Dazu laufen 2 Threads.

    Abb. 1
    0X00 0000 0000
    0000 0X00 0000
    0000 0000 0X00

    Thread A verchiebt jede Sekunde die Position des Objektes um die Breite des Arrays (Abb. 1).
    Thread B ist nur für das Zeichnen des Objektes verantwortlich und läuft alle 40 Millisekunden. Er schaut, welche Position hat das Objekt im Array und zeichnet es dann dementsprechend an die berechnete Position.

    Somit funktioniert das ganze auch einwandfrei. Nun hätte ich gerne, dass sich das Objekt in der Sekunde die es Zeit hat "smooth" zur nächsten Position bewegt.
    Wie kann man soetwas bewerkstelligen?

    Meine erste Überlegung war, die Höhe des Objektes durch die 40Ms zu teilen. Das müsste ja prinzipiell die Distanz sein, die ich in jedem Aufruf von Thread B zur aktuellen Y-Position des Objektes hinzuaddieren muss. Aber die Distanz ist ja i.d.R. keine natürliche Zahl (z.B. 26 Pixel / 40ms = 0.65 Pixel/ms) und auf dem Bildschirm habe ich ja nur diskrete Schritte (Pixel) zur Verfügung.

    Wie löst man so etwas bzw. wo habe ich meinen Denkfehler?

    Vielen Dank bereits im Voraus!


  • Mod

    du loest das indem du float benutzt, natuerlich sieht es mit diskreten pixeln dann nicht perfekt aus, aber angenaehert, dein auge kompensiert fuer vieles was nicht perfekt ist. 40ms updates -> 25fps sollte ok sein.

    du solltest vielleicht ueberlegen, ob du das update nicht einfach immer vor dem zeichnen machst, statt einem extra thread, das scheint ein wenig uebertrieben.



  • Hallo Rapso,

    danke für deine Antwort. Ich habe als Datentyp double genommen, dass sollte genau genug sein. Ich habe auch den Fehler in meinem Code gefunden - ich habe an der falschen Stelle gerundet...
    Jetzt sieht das Ergebnis schon ganz gut aus bis auf eine Kleinigkeit:
    Der Zeichen-Thread braucht ja selbst eine gewisse Zeit zum zeichnen der OpenGL-Sachen, diese Zeit summiert sich bis zur nächsten Ausführung von Thread A auf, sodass mir ein paar Pixel fehlen 😞

    Vereinfacht sieht das Ganze so aus

    while(doRendering){
    
    renderSth();
    msleep(40);
    
    }
    

    Um das Problem zu lösen müsste ich die Zeit ermitteln, die renderSth() tatsächlich benötigt und diese von den 40ms abziehen. Ich habe schon verschiedene Methoden probiert (clock(), boost::chrono), um die Zeit zu messen, aber mir scheint, dass das nicht so trivial ist...

    while(doRendering){
    
    //Startzeit messen
    renderSth();
    //Endzeit messen
    //Differenz zwischen Startzeit und Endzeit berechnen
    msleep(40 /* - Differenz */);
    
    }
    

    Wie kann man diese Zeitmessung realisieren?

    Gruß, ChillSn


Anmelden zum Antworten