Tutorial Allegro 5 #10 – Timers

Padrão

Olá de novo! Hoje temos mais um post da nossa série sobre a biblioteca Allegro 5. Dessa vez, vamos falar sobre o uso de Timers. Eles geralmente são utilizados para disparar ações ou controlar eventos baseados em medidas de tempo.

Assim, vamos fazer um exemplo utilizando dois timers: o primeiro deles será responsável por controlar a cor do plano de fundo da janela, de forma que inicie em preto e vá gradativamente alternando para branco, retornando novamente ao preto e assim sucessivamente. Já o segundo timer exibirá um cronômetro na tela, que será incrementado a cada 1 segundo.

Vamos ver o código e em seguida discutimos seu funcionamento.

#include &lt;allegro5/allegro.h&gt;<br />
#include &lt;allegro5/allegro_font.h&gt;<br />
#include &lt;allegro5/allegro_ttf.h&gt;<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdbool.h&gt;</p>
<p>bool inicializar();</p>
<p>const int LARGURA_TELA = 640;<br />
const int ALTURA_TELA = 480;</p>
<p>ALLEGRO_DISPLAY *janela = NULL;<br />
ALLEGRO_EVENT_QUEUE *fila_eventos = NULL, *fila_contador = NULL;<br />
ALLEGRO_TIMER *timer = NULL, *contador = 0;<br />
ALLEGRO_FONT *fonte = NULL;</p>
<p>int main(void)<br />
{<br />
    bool sair = false;<br />
    int r = 0, g = 0, b = 0;<br />
    int min = 0, seg = 0;</p>
<p>    if (!inicializar())<br />
    {<br />
        return -1;<br />
    }</p>
<p>    al_start_timer(timer);<br />
    al_start_timer(contador);</p>
<p>    while (!sair)<br />
    {<br />
        if (!al_is_event_queue_empty(fila_eventos))<br />
        {<br />
            ALLEGRO_EVENT evento;<br />
            al_wait_for_event(fila_eventos, &amp;evento);</p>
<p>            if (evento.type == ALLEGRO_EVENT_TIMER)<br />
            {<br />
                if (++r &gt;= 255) r = 0;<br />
                if (++g &gt;= 255) g = 0;<br />
                if (++b &gt;= 255) b = 0;<br />
            }<br />
            else if (evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE)<br />
            {<br />
                sair = true;<br />
            }<br />
        }</p>
<p>        if (!al_is_event_queue_empty(fila_contador))<br />
        {<br />
            ALLEGRO_EVENT evento;<br />
            al_wait_for_event(fila_contador, &amp;evento);</p>
<p>            if (evento.type == ALLEGRO_EVENT_TIMER)<br />
            {<br />
                seg++;<br />
                if (seg == 60)<br />
                {<br />
                    min++;<br />
                    seg = 0;<br />
                }<br />
            }<br />
        }</p>
<p>        al_clear_to_color(al_map_rgb(r, g, b));<br />
        al_draw_textf(fonte, al_map_rgb(255, 0, 0), LARGURA_TELA / 2, 200, ALLEGRO_ALIGN_CENTRE, &quot;%d:%d&quot;, min, seg);<br />
        al_flip_display();<br />
    }</p>
<p>    al_destroy_timer(timer);<br />
    al_destroy_event_queue(fila_eventos);<br />
    al_destroy_display(janela);</p>
<p>    return 0;<br />
}</p>
<p>bool inicializar()<br />
{<br />
    if (!al_init())<br />
    {<br />
        fprintf(stderr, &quot;Falha ao inicializar Allegro.\n&quot;);<br />
        return false;<br />
    }</p>
<p>    al_init_font_addon();</p>
<p>    if (!al_init_ttf_addon())<br />
    {<br />
        fprintf(stderr, &quot;Falha ao inicializar allegro_ttf.\n&quot;);<br />
        return false;<br />
    }</p>
<p>    janela = al_create_display(LARGURA_TELA, ALTURA_TELA);<br />
    if (!janela)<br />
    {<br />
        fprintf(stderr, &quot;Falha ao criar janela.\n&quot;);<br />
        return false;<br />
    }</p>
<p>    al_set_window_title(janela, &quot;Testandos Timers...&quot;);</p>
<p>    fila_eventos = al_create_event_queue();<br />
    if (!fila_eventos)<br />
    {<br />
        fprintf(stderr, &quot;Falha ao criar fila de eventos.\n&quot;);<br />
        al_destroy_display(janela);<br />
        return false;<br />
    }</p>
<p>    timer = al_create_timer(0.1);<br />
    if (!timer)<br />
    {<br />
        fprintf(stderr, &quot;Falha ao criar timer.\n&quot;);<br />
        al_destroy_event_queue(fila_eventos);<br />
        al_destroy_display(janela);<br />
        return false;<br />
    }</p>
<p>    fonte = al_load_font(&quot;font.ttf&quot;, 120, 0);<br />
    if (!fonte)<br />
    {<br />
        fprintf(stderr, &quot;Falha ao carregar fonte.\n&quot;);<br />
        al_destroy_timer(timer);<br />
        al_destroy_event_queue(fila_eventos);<br />
        al_destroy_display(janela);<br />
        return false;<br />
    }</p>
<p>    contador = al_create_timer(1.0);<br />
    if (!contador)<br />
    {<br />
        fprintf(stderr, &quot;Falha ao criar timer.\n&quot;);<br />
        al_destroy_font(fonte);<br />
        al_destroy_timer(timer);<br />
        al_destroy_event_queue(fila_eventos);<br />
        al_destroy_display(janela);<br />
        return false;<br />
    }</p>
<p>    fila_contador = al_create_event_queue();<br />
    if (!fila_contador)<br />
    {<br />
        fprintf(stderr, &quot;Falha ao criar fila do contador.\n&quot;);<br />
        al_destroy_timer(contador);<br />
        al_destroy_font(fonte);<br />
        al_destroy_timer(timer);<br />
        al_destroy_event_queue(fila_eventos);<br />
        al_destroy_display(janela);<br />
        return false;<br />
    }</p>
<p>    al_register_event_source(fila_eventos, al_get_display_event_source(janela));<br />
    al_register_event_source(fila_eventos, al_get_timer_event_source(timer));<br />
    al_register_event_source(fila_contador, al_get_timer_event_source(contador));</p>
<p>    return true;<br />
}

Neste código, temos o tipo ALLEGRO_TIMER para a declaração das variáveis de controle de nossos dois timers (timer e contador). Para diferenciarmos os eventos referentes de um ou de outro timer, vamos também criar duas filas de eventos (fila_eventos e fila_contador). Muito provavelmente deve ter uma forma mais “elegante” de se fazer a diferenciação… então, se eu achar, eu atualizo o post.

Continuando, a inicialização dos timers é feita chamando-se a função al_create_timer(), que recebe o timer em questão e o intervalo de tempo no qual ele disparará seus eventos. No nosso caso, o timer timer (responsável pela atualização da tela) será disparado a cada 100 milissegundos (0.1) e o timer contador será disparado a cada 1 segundo (1.0). No final da inicialização, vinculamos cada um dos timers a uma fila de eventos.

Já na função main(), na nossa lógica de tratamento de eventos, comparamos o tipo ALLEGRO_EVENT_TIMER que corresponde a eventos disparados por timers. Caso o evento seja do timer timer, incrementamos o nível de cor (r = vermelho, g = verde, b = azul), zerando-o caso exceda 255 (máximo). No caso do timer contador, fazemos o controle de minutos e segundos (com as variáveis min e seg).

Ao final, executamos as rotinas para atualização da tela (fundo e contador). Temos, então, o programa rodando assim:

Para linkar, precisamos incluir os add-ons allegro_font e allegro_ttf, que utilizamos para mostrar a hora na tela.

  • Windows: -lallegro-5.0.5-mt -lallegro_font-5.0.5-mt -lallegro_ttf-5.0.5-mt
  • Linux: -lallegro -lallegro_font -lallegro_ttf

Bom, é isso. Espero que tenham gostado do post e fiquem atentos, pois tem mais coisa vindo por aí logo logo! Até lá