Aprendendo Allegro 5
Início Janela Imagens Mensagem Fontes e texto Eventos Mouse Teclado Audio Timer Animações Sprites Jogo exemplo

Criando temporizadores

Os timers, ou temporizadores funcionam basicamente como se fossem cronômetros com um tempo definido. A cada intervalor deste tempo, eles disparam um evento. Então podemos utilizar este evento para realizar qualquer tarefa desejada no programa.

Neste exemplo, a janela fica mudando de cor ao longo do tempo, começando no preto, então oscilando os tons de vermelho, então de volta ao preto. Após, o mesmo é feito para o verde, e por fim com a cor azul. e assim o processo se repete.

#include <allegro5/allegro.h>
#include <allegro5/allegro_native_dialog.h>

//fps = frames per second = atualizacoes por segundo
#define FPS 60.0
#define LARGURA_TELA 640
#define ALTURA_TELA 480

ALLEGRO_DISPLAY *janela = NULL;
ALLEGRO_EVENT_QUEUE *fila_eventos = NULL;
//declara o timer do programa
ALLEGRO_TIMER *timer = NULL;

void error_msg(char *text){
	al_show_native_message_box(NULL,"ERRO",
		"Ocorreu o seguinte erro e o programa sera finalizado:",
		text,NULL,ALLEGRO_MESSAGEBOX_ERROR);
}

int inicializar(){
    if (!al_init()){
        error_msg("Falha ao inicializar a Allegro");
        return 0;
    }

    //cria o timer com o intervalo de tempo que ele ira disparar
    timer = al_create_timer(1.0 / FPS);
    if(!timer) {
        error_msg("Falha ao criar temporizador");
        return 0;
    }

    janela = al_create_display(LARGURA_TELA, ALTURA_TELA);
    if(!janela) {
        error_msg("Falha ao criar janela");
        al_destroy_timer(timer);
        return 0;
    }

    al_set_window_title(janela, "Utilizando timers");

    fila_eventos = al_create_event_queue();
    if(!fila_eventos) {
        error_msg("Falha ao criar fila de eventos");
        al_destroy_timer(timer);
        al_destroy_display(janela);
        return 0;
    }

    al_register_event_source(fila_eventos, al_get_display_event_source(janela));
    //registra o timer na fila de eventos
    al_register_event_source(fila_eventos, al_get_timer_event_source(timer));
    al_clear_to_color(al_map_rgb(0,0,0));
    al_flip_display();
    //inicia a contagem do timer
    al_start_timer(timer);

    return 1;
}

int main(void){
    //flag que determina quando a tela precisa ser atualizada
    int desenha = 1;
    //flag que determina quando devemos sair do loop principal
    int sair = 0;
    //vetor que guarda as componentes RGB que sera impresso no fundo da tela
    int cor[3]={0,0,0};
    //i= indice que acessamos o veror
    //inc= direcao que a cor incremente, ou ele sera +1 ou -1
    int i=0,inc=1;


    if (!inicializar()){
        return -1;
    }

    while(!sair){
        ALLEGRO_EVENT evento;
        al_wait_for_event(fila_eventos, &evento);

        /* -- EVENTOS -- */
        //se o tipo do evento for o disparo de um timer
        if(evento.type == ALLEGRO_EVENT_TIMER){
            cor[i]+=inc;
            if (cor[i]>=255)
                inc*=-1;
            if (cor[i]<=0){
                i=(i+1)%3;
                inc*=-1;
            }
            desenha = 1;
        }
        else if(evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
            sair = 1;
        }

        /* -- ATUALIZA TELA -- */
        if(desenha && al_is_event_queue_empty(fila_eventos)) {
            al_clear_to_color(al_map_rgb(cor[0],cor[1],cor[2]));
            al_flip_display();
            //zera flag para nao entrar aqui no proximo loop
            desenha = 0;
        }
    }

    al_destroy_timer(timer);
    al_destroy_display(janela);
    al_destroy_event_queue(fila_eventos);

    return 0;
}

Na linha 5 criamos a constante FPS que será usada para definir o tempo do timer.

ALLEGRO_TIMER

Na linha 12 declaramos a variável do tipo ALLEGRO_TIMER, que serve para definir um temporizador, usado para disparar um evento a cada intervalo de tempo.

al_create_timer()

Na linha 27 chamamos a função al_create_timer() que inicializa o timer. Ela recebe por parâmetro o tempo, em segundos, que será o intervalo de tempo que o timer irá disparar. Este disparo, também chamado de tick, será detectado por um evento. Um timer, quando criado, inicia desativado.

al_get_timer_event_source()

Na linha 52 chamamos a função al_register_event_source() para registrar uma fonte de eventos na fila_eventos. A fonte de eventos passada por parâmetro é a fonte de eventos do timer, retornada pela função al_get_timer_event_source().

al_start_timer()

Na linha 56 chamamos a função al_start_timer(), que serve ativar o timer. A cada tick, ele irá gerar um evento, que poderá ser tratado pelo programa.

Lógica do programa

83-92
98-103
  1. Verificar se existem eventos;
  2. Caso exista evento do timer, atualiza o vetor cor, e seta a flag desenha=1;
  3. Caso desenha==1, atualiza a tela.

Na linha 63 criamos a flag desenha. Ela será usada para verificar quando houve um evento de disparo do timer. A cada iteração do loop, o valor desta variável é verificado (linha 98). Se ela estiver em 0, a tela não será atualizada. Quando o evento disparar (linha 83), a flag receberá desenha=1 (linha 91).

Na linha 67 criamos o vetor cor[3]. Cada posição do vetor irá receber um valor, que representará as componentes RPG que resultará na cor que será usada para preencher o fundo da janela na linha 99.

Na linha 70 criamos as variáveis i e inc. A primeira servirá para saber qual posição do vetor cor será acessado dentro do if da linha 83. A segunda variável irá determinar se a cor deverá ao longo do tempo ficando mais clara ou mais escura. Na linha 84 o vetor irá acumular o valor +1 ou -1, dependendo do valor de inc (modificado nas linhas 86 e 89).

ALLEGRO_EVENT_TIMER

Na linha 83 verificamos se o tipo do evento é ALLEGRO_EVENT_TIMER, que é o evento disparado por um temporizador.

Em caso afirmativo, na linha 84 somamos +1 ou -1 ao vetor cor. Nas linhas 85 e 87 verificamos se o vetor na posição analisada chegou ao seus limites, ou seja, 0 ou 255 (pois são os lmites de representação de cada componente RGB). Em caso afirmativo, invertemos o sinal da variável inc(linhas 86 e 89).

Na linha 88, incrementamos a variável i, porém aplicando o resto da divisão por 3, fazendo com que os valores da variável vão de 0 até 2, posi a variável irá acessar as posições do vetor.

Os valores do vetor vão variar da seguinte maneira:

  1. cor[0](R) irá variar de 0 até 255;
  2. cor[0](R) irá variar de 255 até 0;
  3. cor[1](G) irá variar de 0 até 255;
  4. cor[1](G) irá variar de 255 até 0;
  5. cor[2](B) irá variar de 0 até 255;
  6. cor[2](B) irá variar de 255 até 0.

Na linha 98 testamos se a flag desenha!=0 e também não há mais eventos esperando na fila. Em caso aformativo, atualizamos a tela, mostrando a cor determinada pelo vetor cor. Então à variável desenha=0. Isto evitará que a cada iteração do loop principal, a tela seja mostrada, fazendo com que isto aconteça somente quando o evento do timer for disparado, o que acontece 60 vezes por segundo.

Outros links