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 0X00Thread 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!
-
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 fehlenVereinfacht 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