Tutorial Allegro 5 #6 – Utilizando o Teclado

Padrão

Olá pessoal! Temos hoje mais um post da série sobre Allegro 5. Desta vez, veremos como manipular as entradas vindas do teclado.

Como vocês verão no código, o tratamento, assim como no mouse, é realizado através da manipulação de eventos. O aplicativo consiste em exibir na tela qual das setas é pressionada. Coisa simples, mas que permitirá verificar como tratar estes eventos vindos do teclado.

Assim como das outras vezes, vamos dar uma olhada no código e comentar sobre o que tem de novo nele.

#include <allegro5/allegro.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_image.h>
#include <stdio.h>
#include <stdbool.h>

const int LARGURA_TELA = 640;
const int ALTURA_TELA = 480;

ALLEGRO_DISPLAY *janela = NULL;
ALLEGRO_EVENT_QUEUE *fila_eventos = NULL;
ALLEGRO_BITMAP *fundo = NULL;
ALLEGRO_FONT *fonte = NULL;

bool inicializar();

int main(void)
{
    bool sair = false;
    int tecla = 0;

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

    al_draw_bitmap(fundo, 0, 0, 0);

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

            if (evento.type == ALLEGRO_EVENT_KEY_DOWN)
            {
                switch(evento.keyboard.keycode)
                {
                case ALLEGRO_KEY_UP:
                    tecla = 1;
                    break;
                case ALLEGRO_KEY_DOWN:
                    tecla = 2;
                    break;
                case ALLEGRO_KEY_LEFT:
                    tecla = 3;
                    break;
                case ALLEGRO_KEY_RIGHT:
                    tecla = 4;
                    break;
                }
            }
            else if (evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
            {
                sair = true;
            }
        }

        if (tecla)
        {
            al_draw_bitmap(fundo, 0, 0, 0);

            switch (tecla)
            {
            case 1:
                al_draw_text(fonte, al_map_rgb(255, 255, 255), LARGURA_TELA / 2,
                        ALTURA_TELA / 2 - al_get_font_ascent(fonte) / 2,
                        ALLEGRO_ALIGN_CENTRE, "Seta para cima");
                break;
            case 2:
                al_draw_text(fonte, al_map_rgb(255, 255, 255), LARGURA_TELA / 2,
                        ALTURA_TELA / 2 - al_get_font_ascent(fonte) / 2,
                        ALLEGRO_ALIGN_CENTRE, "Seta para baixo");
                break;
            case 3:
                al_draw_text(fonte, al_map_rgb(255, 255, 255), LARGURA_TELA / 2,
                        ALTURA_TELA / 2 - al_get_font_ascent(fonte) / 2,
                        ALLEGRO_ALIGN_CENTRE, "Seta esquerda");
                break;
            case 4:
                al_draw_text(fonte, al_map_rgb(255, 255, 255), LARGURA_TELA / 2,
                        ALTURA_TELA / 2 - al_get_font_ascent(fonte) / 2,
                        ALLEGRO_ALIGN_CENTRE, "Seta direita");
                break;
            }

            tecla = 0;
        }

        al_flip_display();
    }

    al_destroy_display(janela);
    al_destroy_event_queue(fila_eventos);

    return 0;
}

bool inicializar()
{
    if (!al_init())
    {
        fprintf(stderr, "Falha ao inicializar a Allegro.\n");
        return false;
    }

    al_init_font_addon();

    if (!al_init_ttf_addon())
    {
        fprintf(stderr, "Falha ao inicializar add-on allegro_ttf.\n");
        return false;
    }

    if (!al_init_image_addon())
    {
        fprintf(stderr, "Falha ao inicializar add-on allegro_image.\n");
        return false;
    }

    if (!al_install_keyboard())
    {
        fprintf(stderr, "Falha ao inicializar o teclado.\n");
        return false;
    }

    janela = al_create_display(LARGURA_TELA, ALTURA_TELA);
    if (!janela)
    {
        fprintf(stderr, "Falha ao criar janela.\n");
        return false;
    }

    al_set_window_title(janela, "Utilizando o Teclado");

    fonte = al_load_font("comic.ttf", 72, 0);
    if (!fonte)
    {
        fprintf(stderr, "Falha ao carregar \"fonte comic.ttf\".\n");
        al_destroy_display(janela);
        return false;
    }

    fila_eventos = al_create_event_queue();
    if (!fila_eventos)
    {
        fprintf(stderr, "Falha ao criar fila de eventos.\n");
        al_destroy_display(janela);
        return false;
    }

    fundo = al_load_bitmap("bg.jpg");
    if (!fundo)
    {
        fprintf(stderr, "Falha ao carregar imagem de fundo.\n");
        al_destroy_display(janela);
        al_destroy_event_queue(fila_eventos);
        return false;
    }

    al_register_event_source(fila_eventos, al_get_keyboard_event_source());
    al_register_event_source(fila_eventos, al_get_display_event_source(janela));

    return true;
}

Bom, visivelmente podemos citar a mudança na estrutura do programa. Desta vez, isolamos todas as tarefas relativas a inicialização do programa em uma função, que retorna um valor booleano. Como estamos fazendo o programa em C, para utilizar o tipo booleano é necessário incluir o arquivo stdbool.h no início. Nas variáveis básicas de nosso programa, não temos nenhuma novidade – apenas o fato de que as declaramos como globais. Ao iniciar o programa, temos a nossa flag indicadora de saída e uma variável inteira chamada tecla que representará qual das setas pressionamos. Em seguida há uma chamada à função de inicialização, onde podemos destacar a inicialização do teclado, através da função al_install_keyboard() e a consequente vinculação dos eventos originados nele à nossa fila, através da função al_register_event_source() recebendo como argumento o retorno da função al_get_keyboard_event_source().

Após as inicializações, iniciamos o looping do nosso programa. Da mesma forma que o aplicativo do mouse (post anterior), verificamos a presença de eventos e, caso existam, fazemos o seu tratamento. Desta vez, estamos relevando os eventos do tipo ALLEGRO_EVENT_KEY_DOWN, que indicam quando o usuário pressionou alguma tecla do teclado. Através do campo keyboard do evento, temos acesso a diversos dados, que possivelmente usaremos em tutoriais futuros. Para este, comparamos o conteúdo de keycode, comparando com as constantes que representam todas as teclas. No caso do exemplo, comparamos somente com as setas, que é o que nos interessa. De acordo com o valor do keycode, atribuímos um determinado valor a essa variável.

Por fim, fazemos uma verificação sobre o conteúdo da variável tecla, para decidirmos o que deve ser escrito na tela. Caso seu valor seja 0, então não há necessidade de atualizar a tela.

O aplicativo rodando fica assim:

Para compilar, precisaremos de alguns add-ons, ficando assim:

  • Windows: -lallegro-5.0.4-mt -lallegro_font-5.0.4-mt -lallegro_ttf-5.0.4-mt -lallegro_image-5.0.4-mt
  • Linux: -lallegro -lallegro_font -lallegro_ttf -lallegro_image

Bem pessoal, é isso. Os dois arquivos utilizados no tutorial (fonte e fundo) podem ser baixados aqui. Como podem perceber, desde que o conceito estrutural da biblioteca Allegro esteja fixado, o aprendizado de novas funcionalidades acaba se tornando natural e bem mais fácil.

Então, até a próxima!

  • casca-sama

    Olá, amigo, eu utilizei o algoritmo que você mostrou, porém ele só funciona para uma tecla pressionada uma vez, ou seja, se eu segurar a tecla, ele não repete, tem alguma forma de resolver isso?

  • Michael Douglas Pacheco

    Esse código travou meu ubuntu todo 100%