2010-12-19 5 views
0

これはlazyfooのSDLチュートリアルのチュートリアルページthisに関するものです。そこではまず、タイマーを起動して、リフレッシュされる前に各フレームが生き続ける時間を計算します。彼は、この私がfps.get_ticks()は常に0(??)を返しますので、必要のない上記ではないことがわかってきましたが、次のFPSを設定するときにSDLでタイマーを開始するのはなぜですか?

if((cap == true) && (fps.get_ticks() < 1000/FRAMES_PER_SECOND)) { 
//Sleep the remaining frame time 
SDL_Delay((1000/FRAMES_PER_SECOND) - fps.get_ticks()); 
} 

を使用して(?)、私たちは完全に除外カントありませんタイマーは1000/FPSのためにちょうど遅れます。

私は以下の両方の方法を試してみましたが、どちらも同じことを私に与えています。私はここで何が欠けているのですか、なぜタイマーが必要ですか?

#include "SDL/SDL.h" 
#include "SDL/SDL_image.h" 
#include <iostream> 
SDL_Surface *background = NULL; 
SDL_Surface *screen = NULL; 
SDL_Surface *msg = NULL; 
const int FPS = 20; 

void initialize(void){ 
    if (SDL_Init(SDL_INIT_EVERYTHING) == -1){ 
     std::cout<<"could not start sdl"<<std::endl; 
    } 

    screen = SDL_SetVideoMode(640,480,32,SDL_SWSURFACE); 
    if (screen == NULL){ 
     std::cout<<"could not make screen"<<std::endl; 
    } 

} 
void cleanUp(void){ 
    SDL_Quit(); 
    SDL_FreeSurface(background); 
    SDL_FreeSurface(msg); 
} 
void loadFiles(void){ 
    background = IMG_Load("background.bmp"); 
    msg = IMG_Load("msg.bmp"); 
    if (background == NULL){ 
     std::cout<<"could not load background"<<std::endl; 
    } 
    if (msg == NULL){ 
     std::cout<<"could not load msg"<<std::endl; 
    } 
} 
void blitSurf(int x,int y,SDL_Surface *source,SDL_Surface *dest){ 
    SDL_Rect dest_pos; 
    dest_pos.x = x; 
    dest_pos.y = y; 

    if (SDL_BlitSurface(source,NULL,dest,&dest_pos) == -1){ 
     std::cout<<"could not blit surface"<<std::endl; 
    } 
} 
void update(void){ 
    if (SDL_Flip(screen) == -1){ 
     std::cout<<"could not update screen"<<std::endl; 
    } 
} 

int main(int argc,char *argv[]){ 
    initialize(); 
    loadFiles(); 

    bool running = true; 
    bool cap = false; 
    int msg_pos_y = 0; 
    int start = 0; 
    int temp = 0; 
    SDL_Event event; 
    while (running == true){ 
     start = SDL_GetTicks(); 

     while (SDL_PollEvent(&event)){ 
      if (event.type == SDL_KEYDOWN){ 
       if (event.key.keysym.sym == SDLK_c){ 
        if(cap == false){ 
         cap = true; 
         std::cout<<"cap set to, true"<<std::endl; 
        }else{ 
         cap = false; 
         std::cout<<"cap set to, false"<<std::endl; 
        } 
       } 
      } 
      if (event.type == SDL_QUIT){ 
        running = false; 
        std::cout<<"Quit was pressed"<<std::endl; 
      } 
     } 

     blitSurf(0,0,background,screen); 
     if (msg_pos_y < 640){ 
      blitSurf(200,msg_pos_y,msg,screen); 
      msg_pos_y++; 
     }else{ 
      msg_pos_y = 0; 
      blitSurf(200,msg_pos_y,msg,screen); 
     } 
     update(); 


     if ((cap == true) && ((SDL_GetTicks()-start) < (1000/FPS))){ 
      SDL_Delay((1000/FPS) - (SDL_GetTicks()-start)); 
     } 

     /* this works as well ?? 
     if (cap == true){ 
      SDL_Delay(1000/FPS); 
     } 
     */ 
    } 

    cleanUp(); 
    return 0; 
} 

答えて

1

たとえば、50 fpsが必要です。

1000ミリ秒/ 50 = 20ミリ秒の遅延。

しかし、何をしていても、レンダリングや物理計算、AIの計算には時間がかかります。私が書いたすべてのものが10ミリ秒かかるとしよう。あなたは1000ミリ秒/(20msの遅延+ 10msのすべて)= 33.3フレーム/秒です。この10msを遅延から引く必要があります。

+0

歓声、しかし、ループ繰り返しながら、私は最初は非常に上下に二にあること、1で2回)(SDL_GetTicksを呼び出してテストプログラムを書きました。両方とも同じ結果を生み出し、タイミングも変わりません。ループがより複雑で、AIや物理など何かを持っていたらタイミングが違うのだろうか? – silent

+1

はい、あなたが時間を費やして何かをやっているなら、彼らは違うでしょう。 – damian

+0

それに感謝します。 – silent

0

は、私は専門家だが、何彼がすることです:あなたのSDLアプリが終了され実行されますあなたのメインループ一度あなたが自分のものをやっていたが、時間が少し経過していること(ブリッティングとすべてのものの描画)たとえば、フレームを描画するのに10msかかった場合は、次のフレームまで10ms(1000/FPS)を待たなければなりません。そうしないと、フレームが長すぎます。

+0

これは私が思ったものですが、1回のループ反復でSDL_GetTicks()関数を2回呼び出すと同じ結果(?)が返されます。したがって、if文で 'fps.get_ticks()'は実際にはget_ticks関数の中から0( 'SDL_GetTicks() - startTicks;)を返します。これが私が混乱している理由です。 – silent

関連する問題