Bewegung gleichmäßig darstellen
-
Hallo,
ich versuche mit SDL ein sich bewegendes Bild unabhängig von der Framerate darstellen zu lassen. Dabei bewegt sich own.bmp (ein 5sec Paint Bild) von links nach rechts über den Screen. Ich habe dieses Testprogramm erstellt, um zu überprüfen, ob FPS-Unabhängige-Bewegung funktioniert, aber es klappt nicht und ich finde den Fehler nicht.
Ich lasse das Programm zweimal starten: Einmal drücke ich SDLK_LEFT (linke Pfeiltaste), wodurch 300 mal cb.bmp auf den Bildschirm gezeichnet wird und einmal drücke ich es nicht, es ist also nur ein Bild (bzw. zwei) auf dem Bildschirm. Die FPS ist bei 300 Bildern ca. bei 10 und bei dem anderen ca. 350.
Trotz meiner Berechnung des "Movement Value" (übrigens von diesem Tutorial: http://www.gamedev.net/reference/articles/article1604.asp ) bewegt sich ein own.bmp immer schneller.
P.S.: Der nachfolgende Code ist der CodeBlocks Standard SDL Code mit ein paar Veränderungen von dem Tutorial.
Wenn ihr es auch testen möchtet, braucht ihr zwei 5sec-Paint-Bilder namens "own.bmp" und "cb.bmp".P.P.S.: Bei Enter bewegt sich das Bild.
#include <SDL/SDL.h> #include <iostream> #include <cstdlib> #include <ctime> using namespace std; int main ( int argc, char *argv[] ) { srand(time(0)); int count = 0, r = 0; // initialize SDL video SDL_Init( SDL_INIT_VIDEO ); // make sure SDL cleans up before exit atexit(SDL_Quit); // create a new window SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE|SDL_DOUBLEBUF); // load an image SDL_Surface* bmp = SDL_LoadBMP("cb.bmp"); SDL_Surface* own = SDL_LoadBMP("own.bmp"); // centre the bitmap on screen SDL_Rect dstrect, dst; dst.x = 0; dst.y = 0; dstrect.x = (screen->w - bmp->w) / 2; dstrect.y = (screen->h - bmp->h) / 2; // program main loop bool done = false; /****************************************************/ int v = 0; Uint32 timerdiff; double secsperframe; //used to hold the value for how many seconds have elapsed between frames const double desireddistance = 2.0f; //desired distance to move in a second double movementvalue = 0.0f; //value to move by each frame Uint32 timer = SDL_GetTicks(); //the last recorded time. /****************************************************/ while (!done) { // message processing loop SDL_Event event; while (SDL_PollEvent(&event)) { // check for messages switch (event.type) { // exit if the window is closed case SDL_QUIT: done = true; break; // check for keypresses case SDL_KEYDOWN: { if(event.key.keysym.sym == SDLK_LEFT) count = 300; if(event.key.keysym.sym == SDLK_RIGHT) count = 0; if(event.key.keysym.sym == SDLK_RETURN) v = 1; if(event.key.keysym.sym == SDLK_BACKSPACE) v = 0; // exit if ESCAPE is pressed if (event.key.keysym.sym == SDLK_ESCAPE) done = true; break; } } // end switch } // end of message processing /****************************************************/ if(v == 1) // movement { double s = (double)1000.0f * movementvalue; cout << "s = " << s << "\tr = " << r << "\tFPS: " << (int)(1.0f / secsperframe) << endl; dst.x += s; if(dst.x > 640-1){ dst.x = 0; r++; } } /****************************************************/ // DRAWING STARTS HERE // clear screen SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0)); // draw bitmap SDL_BlitSurface(bmp, 0, screen, &dstrect); for(int i = 0; i < count; ++i) { SDL_Rect temp; temp.x = rand() % 640; temp.y = rand() % 480; SDL_BlitSurface(bmp, 0, screen, &temp); } SDL_BlitSurface(own, 0, screen, &dst); SDL_Flip(screen); /****************************************************/ //first determine how many milliseconds elapsed timerdiff = SDL_GetTicks() - timer; //the function reads in milliseconds so convert to seconds by dividing by 1000 secsperframe=(double)((double)timerdiff/(double)1000.0f); //now compute the movement value movementvalue = desireddistance * secsperframe; //get the new time timer = SDL_GetTicks(); /****************************************************/ } // end main loop // free loaded bitmap SDL_FreeSurface(bmp); // all is well ;) printf("Exited cleanly\n"); return 0; }Danke für eure Hilfe!
-
Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum Spiele-/Grafikprogrammierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
baron schrieb:
Hallo,
Trotz meiner Berechnung des "Movement Value" (übrigens von diesem Tutorial: http://www.gamedev.net/reference/articles/article1604.asp ) bewegt sich ein own.bmp immer schneller.
double movementvalue = 0.0f; //value to move by each frameNur ein Anreiz, ohne den Source komplett gelesen oder gar kompiliert zu haben: "value to move by each frame" ist vielleicht unpraktisch, wenn die fps mal steigt und mal sinkt.
Mach die Position Deiner Elemente von der Zeit abhängig, nicht von der Anzahl der schon ausgegebenen Bilder.
-
du musst alle geschwindigkeiten in px/sec angeben, oder etwas Äquivalentem. Dann für jeden Frame die vergangene Zeit in Sekunden, und diesen Faktor bei absolut jeder Berechnung, die die Geschwindig nutzt um eine neue Position zu berechnen als Faktor hinzunehmen. Das ist der mir einzig sinnvolle Ansatz. Mit den FPS die pro-Frame-Geschwindigkeit zu berechnen ist nicht unbedingt der richtige ansatz und weil unkonventionell auch sehr unübersichtlich.
-
Ich berechne doch die Zeitdifferenz und nutze die dann als Faktor.
Könnt ihr mir das vielleicht ein wenig ausführlicher erklären? Ich verstehe nicht ganz recht, was ihr meint

der baron
-
trenne am besten einfach gameticks und "realtime-ticks"
while(meineschleifeläuftnoch) { //Irgendwo hier zeitmessen if(30ms vorbei) { //GAMETICK if(benutzer drückt "dies und das") bewege_futzi(x,y); } rendern(); }edit: omg tags