Pergunta

Eu estou construindo um jogo em 3D a partir do zero em C ++ usando OpenGL e SDL no linux como um hobby e para aprender mais sobre esta área de programação.

Quer saber sobre a melhor maneira de tempo simular enquanto o jogo está em execução. Obviamente, eu tenho um loop que é algo como:

void main_loop()
{
    while(!quit)
    {
         handle_events();
         DrawScene();
         ...
         SDL_Delay(time_left());
    }
}

Eu estou usando o SDL_Delay e TIME_LEFT () para manter um framerate de cerca de 33 fps.

Eu tinha pensado que eu só preciso de algumas variáveis ??globais como

int current_hour = 0;
int current_min = 0;
int num_days = 0;
Uint32 prev_ticks = 0;

Em seguida, uma função como:

void handle_time()
{
    Uint32 current_ticks;
    Uint32 dticks;
    current_ticks = SDL_GetTicks();
    dticks = current_ticks - prev_ticks; // get difference since last time

    // if difference is greater than 30000 (half minute) increment game mins
    if(dticks >= 30000) {
         prev_ticks = current_ticks;
         current_mins++;
         if(current_mins >= 60) {
            current_mins = 0;
            current_hour++;
         }
         if(current_hour > 23) {
            current_hour = 0;
            num_days++;
         }
    }
 }

e, em seguida, chamar a função handle_time () no circuito principal.

Ele compila e executa (usando printf para escrever a tempo para o console no momento), mas eu estou querendo saber se esta é a melhor maneira de fazê-lo. É maneiras há mais fácil ou maneiras mais eficientes?

Foi útil?

Solução

Eu já mencionei isso antes em outros tópicos relacionados ao jogo. Como sempre, siga as sugestões por Glenn Fiedler em sua série jogo de física

O que você quer fazer é usar um timestep constante que você se acumulando deltas de tempo. Se você quiser 33 atualizações por segundo, então o seu constante iteração deve ser 1/33. Você também pode chamar isso de freqüência de atualização . Você também deve dissociar a lógica do jogo da prestação como eles não pertencem juntos. Você quer ser capaz de usar uma freqüência de atualização baixa durante o processamento mais rápido que a máquina permite. Aqui está um código de exemplo:

running = true;
unsigned int t_accum=0,lt=0,ct=0;
while(running){
    while(SDL_PollEvent(&event)){
        switch(event.type){
            ...
        }
    }
    ct = SDL_GetTicks();
    t_accum += ct - lt;
    lt = ct;
    while(t_accum >= timestep){
        t += timestep; /* this is our actual time, in milliseconds. */
        t_accum -= timestep;
        for(std::vector<Entity>::iterator en = entities.begin(); en != entities.end(); ++en){
            integrate(en, (float)t * 0.001f, timestep);
        }
    }
    /* This should really be in a separate thread, synchronized with a mutex */
    std::vector<Entity> tmpEntities(entities.size());
    for(int i=0; i<entities.size(); ++i){
        float alpha = (float)t_accum / (float)timestep;
        tmpEntities[i] = interpolateState(entities[i].lastState, alpha, entities[i].currentState, 1.0f - alpha);
    }
    Render(tmpEntities);
}

Este alças undersampling, bem como oversampling. Se você usar um inteiro aritmética, como feito aqui, seus física do jogo deve ser perto de 100% determinista, não importa como lento ou rápido a máquina é. Esta é a vantagem de aumentar a hora em intervalos de tempo fixos. O estado utilizado para processamento é calculado por interpolação entre os estados anteriores e actuais, onde o valor restante no interior do acumulador de tempo é utilizada como o factor de interpolação. Isso garante que a prestação é lisa, não importa quão grande o timestep é.

Outras dicas

Além das questões já apontados (você deve usar uma estrutura para os tempos e passá-lo para handle_time () e sua hora vai ter incrementado a cada meia hora) a sua solução é bom para manter o controle de tempo de execução no jogo.

No entanto, para a maioria dos eventos do jogo que precisam acontecer de vez em quando você provavelmente deve basear-los fora do loop principal do jogo em vez de um tempo real para que eles irão acontecer nas mesmas proporções com um fps diferente.

Uma das mensagens de Glenn você realmente vai querer ler é Fix Your TimeStep . Depois de olhar-se este link notei que Mads direcionado você para o mesmo lugar geral na sua resposta

Eu não sou um desenvolvedor Linux, mas você pode querer ter um olhar para usando Timers em vez de voto para os carrapatos.

http://linux.die.net/man/2/timer_create

EDIT:
SDL Parecem Timers de apoio: SDL_SetTimer

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top