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

Utilizando o teclado

Nesta lição veremos como utilizar a entrada do teclado nos programas. Para isso, usaremos os eventos do allegro. Como já de costume das lições anteriores, o código é mostrado e entrão explicado por partes. Caso alguma parte não tenha sida explicada, provavelmente é porque ela já tenha sido explicada antes, então recomendo voltar algumas lições para aprender bem as partes anteriores.

Este programa abre uma janela, e fica esperando o usuário digitar uma tecla. Caso ele digite as teclas relativas às setas para cima, baixo, esquerda ou direita, um texto colorido aparece na tela enquanto a tecla está sendo pressionada. Caso a tecla ESC for pressionada, ou o usuário clicar para fechar a janela, o programa é encerrado.

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

#define LARGURA_TELA 640
#define ALTURA_TELA 480

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

void error_msg(char *text){
	al_show_native_message_box(janela,"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;
    }

    al_init_font_addon();

    if (!al_init_ttf_addon()){
        error_msg("Falha ao inicializar add-on allegro_ttf");
        return 0;
    }

    if (!al_init_image_addon()){
        error_msg("Falha ao inicializar add-on allegro_image");
        return 0;
    }

    //inicializa addon do teclado
    if (!al_install_keyboard()){
        error_msg("Falha ao inicializar o teclado");
        return 0;
    }

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

    al_set_window_title(janela, "Utilizando o Teclado");

    fonte = al_load_font("arial.ttf", 72, 0);
    if (!fonte){
        error_msg("Falha ao carregar \"arial.ttf\"");
        al_destroy_display(janela);
        return 0;
    }

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

    //registra duas fontes de eventos na fila. o da janela, e do teclado
    al_register_event_source(fila_eventos, al_get_keyboard_event_source());
    al_register_event_source(fila_eventos, al_get_display_event_source(janela));

    return 1;
}

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

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

    al_clear_to_color(al_map_rgb(255, 255, 255));

    while (!sair){
        while(!al_is_event_queue_empty(fila_eventos)){
            ALLEGRO_EVENT evento;
            //espera ate que algum evento esteja na fila
            al_wait_for_event(fila_eventos, &evento);

            //se o evento for pressionar uma tecla
            if (evento.type == ALLEGRO_EVENT_KEY_DOWN){
                //verifica qual tecla foi pressionada
                switch(evento.keyboard.keycode){
                //seta para cima
                case ALLEGRO_KEY_UP:
                    tecla = 1;
                    break;
                //seta para baixo
                case ALLEGRO_KEY_DOWN:
                    tecla = 2;
                    break;
                //seta para esquerda
                case ALLEGRO_KEY_LEFT:
                    tecla = 3;
                    break;
                //seta para direita.
                case ALLEGRO_KEY_RIGHT:
                    tecla = 4;
                    break;
                //esc. sair=1 faz com que o programa saia do loop principal
                case ALLEGRO_KEY_ESCAPE:
                    sair = 1;
                }
            }
            //se o evento foi o soltar de uma tecla
            //tecla=5 significa que alguma foi pressionada mas nao e nenhuma das setas
            else if (evento.type == ALLEGRO_EVENT_KEY_UP){
                tecla = 5;
            }
            //se clicou para fechar a janela
            else if (evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE){
                sair = 1;
            }
        }

        //tecla!=0 significa que algo foi pressionado
        if (tecla){
            al_clear_to_color(al_map_rgb(255, 255, 255));

            //desenha na tela as palavras relativas a seta preesionada
            switch (tecla){
            case 1:
                al_draw_text(fonte, al_map_rgb(0, 255, 0), LARGURA_TELA / 2,
                        ALTURA_TELA / 2 - al_get_font_ascent(fonte) / 2,
                        ALLEGRO_ALIGN_CENTRE, "CIMA");
                break;
            case 2:
                al_draw_text(fonte, al_map_rgb(255, 0, 255), LARGURA_TELA / 2,
                        ALTURA_TELA / 2 - al_get_font_ascent(fonte) / 2,
                        ALLEGRO_ALIGN_CENTRE, "BAIXO");
                break;
            case 3:
                al_draw_text(fonte, al_map_rgb(255, 0, 0), LARGURA_TELA / 2,
                        ALTURA_TELA / 2 - al_get_font_ascent(fonte) / 2,
                        ALLEGRO_ALIGN_CENTRE, "ESQUERDA");
                break;
            case 4:
                al_draw_text(fonte, al_map_rgb(0, 0, 255), LARGURA_TELA / 2,
                        ALTURA_TELA / 2 - al_get_font_ascent(fonte) / 2,
                        ALLEGRO_ALIGN_CENTRE, "DIREITA");
                break;
            }

            //zera a tecla para a proxima vez nao entrar aqui de novo
            tecla = 0;
        }

        al_flip_display();
    }

    al_destroy_display(janela);
    al_destroy_event_queue(fila_eventos);

    return 0;
}

Na linha 19 declaramos a função inicializar(). Esta função será utilizada lá dentro do main(), e ela retorna 0 caso alguma das diversas funções de inicialização do programa falhar, ou 1 caso chegue ao fim com sucesso. Na linha 77 o main verifica as inicializações através desta função. Este processo foi feito por questões de organização de código.

al_install_keyboard()

Na linha 38 chamamos a função al_install_keyboard(), que permite a captura das teclas digitadas no teclado através de eventos.

al_get_keyboard_event_source()

Na linha 66 chamamos a função al_get_keyboard_event_source() receber os eventos do teclado, e usamos o mesmo na função al_register_event_source() para registrar os eventos vindos do teclado na fila de eventos.

ALLEGRO_EVENT_KEY_DOWN

Na linha 90 testamos se o tipo de evento capturado é o ALLEGRO_EVENT_KEY_DOWN, que é o tipo de evento disparado quando é detectado o ato pressionar de uma tecla.

.keyboard.keycode

Na linha 92 fazemos um switch para verificar o valor do campo .keyboard.keycode. Como já foi dito anteriormente, a variável ALLEGRO_EVENT é uma struct com diversos campos. E o campo .keyboard.keycode, em caso de disparo de um evento relativo a uma tecla, possuirá um código referente a qual tecla foi pressionada. Consulte a referência para saber sobre os possíveis keycodes.

Nas linhas 94, 98, 102 e 106 verificamos se as teclas pressionadas são as setas para cima, baixo, esquerda e direita, respectivamente. Em cada caso colocamos um valor arbitrário na variável tecla, que será verificado mais adiante.

ALLEGRO_EVENT_KEY_UP

Na linha 116 verificamos se o evento disparado foi ALLEGRO_EVENT_KEY_UP, que é o evento relacionado ao soltar uma tecla. Em caso verdadeiro, colocamos o valor tecla=5. Este valor vai servir para na parte do código que mostra o texto, o programa saber que é para limpar o conteúdo da tela.

Na linha 120 testamos se o usuário clico no botão de fechar a janela, se sim, colocamos a flag sair=1. Isto fará com que o programa feche na próxima iteração do loop principal (linha 83).

Na linha 126 testamos se tecla!=0. Caso seja, significa que desde a última iteração do loop principal, alguma tecla foi pressionada ou solta. Isto significa que temos que atualizar a tela.

Começamos limpando a tela na linha 127, para então verificar com o switch da linha 130 o valor da tecla. Caso os valores sejam de 1 a 4 significa que o usuário pressionou alguma seta, conforme visto acima. Neste caso, usamos a função al_draw_text para escrever a mensagem na tela. Cada mensagem será de uma cor diferente, todas no centro da tela, com a fonte definida na linha 51.

Como no switch não temos nenhum caso para tecla==5 significa que o progrma apenas limpará a tela (linha 127) sem mostrar nenhum texto.

Ao após escrever o texto, atribuímos tecla=0 para dizer ao programa que não há mais o que atualizar, logo, na próxima vez que o programa chegar na linha 126, se nenhum evento de captura de tecla tiver sido disparado antes, nada mais será escrito.

Download dos arquivos

Outros links