0

これは、lazyfoo の 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() ); 
} 

fps.get_ticks() は常に 0 (??) を返すことがわかったので、上記は不要 (?) ではありませんが、タイマーを完全に省略して 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;
}
4

2 に答える 2

1

50 fps が必要だとしましょう。

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

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

于 2010-12-19T10:20:15.833 に答える
0

私は専門家ではありませんが、彼がしていることは次のとおりです。sdlアプリを実行するメインループが終了すると(ブリッティングなどの描画)、作業中に時間が少し経過した可能性があります。たとえば、10ミリ秒かかった場合フレームを描画するには、次のフレームまで (1000/FPS) - 10 ミリ秒待つ必要があります。そうしないと、フレームが長くなりすぎます。

于 2010-12-19T10:07:54.963 に答える