Utilizando a entrada do mouse

Neste tutorial iremos aprender a como utlilizar o mouse em nossos programas. A captura do movimento e cliques do mouse é feita através dos eventos, aprendidos na lição anterior. Neste exemplos iremos criar duas áreas coloridas, onde uma reagirá com o movimento do mouse, e a outra ao clique do mouse. Vamos ao código:


			
			

No início do programa declaramos algumas variáveis, e iniciamos a biblioteca e addons. Tudo isso já foi visto anteriormente. Vamos direto ao que temos de novo.

al_set_window_title()

Na linha 34 chamamos a função al_set_window_title(), que muda o texto da janela. Ela recebe o display, e a string contendo o texto.

al_install_mouse()

Na linha 37 chamamos a função al_install_mouse(), permite o uso dos eventos relativos à captura de cliques e movimentos do mouse.

al_set_system_mouse_cursor()

Na linha 44 chamamos a função al_install_mouse(), que que serve para definir o tipo de cursor do mouse que será usado em uma determinada janela. Ela recebe como parâmetro o display, e uma flag indicando o tipo de cursor. No exemplo, usamos ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT, que é o cursor padrão. Consulte a referência para conhecer os outros tipos de cursores disponíveis.

al_create_bitmap()

Na linha 51 e linha 59 usamos a função al_create_bitmap(), que cria uma área gráfica, chamada bitmap, nas posições X e Y informadas por parâmetro. Já havíamos trabalhado com a função al_load_bitmap(), que carrega uma imagem em um bitmap. A diferença é que al_create_bitmap() cria a área sem atribuir nada a ela, somente com as dimensões especificadas.

al_get_mouse_event_source()

Note que nas linhas seguintes criamos a fila de eventos (explicada anteriormente) e inicamos a mesma. Na linha 75 porém, usamos como segundo parâmetro de al_register_event_source() (função que faz com que a fila de eventos guarde os eventos de uma determinada fonte de eventos) o retorno da função al_get_mouse_event_source(). Isto faz com que todos eventos relacionados ao mouse sejam registrados na fila de eventos. Diferente desta, lembre-se que na lição anterior havíamos registrado os eventos da janela na fila.

Lógica do problema

Os seguintes passos serão executados, até que a flag sair==0:

  1. Enquanto tiver eventos na fila:
    1. Verifica-se se o cursor do mouse está sobre o bitmap central. Se sim seta a flag na_area_central=1;
    2. Verifica-se se o clique do mouse foi feito sobre o bitmap menor. Se sim, seta a flag sair=1;
  2. Colore os dois bitmaps;
  3. Desenha um deles no centro da janela, e o outro no canto inferior direito;
  4. Atualiza a tela.

Na linha 78 criamos a flag na_area_central que começa em 0, e irá receber 1 quando o mouse estiver sobre o bitmap do centro da janela.

al_is_event_queue_empty()

Na linha 81 usamos a função al_is_event_queue_empty que verifica se a fila de eventos passada por parâmetro está vazia. Como nossa while está condicionado à esta função, este trecho de código só deixará de ser executado quando todos os eventos tiverem sido tratados.

al_wait_for_event()

Neste exemplo, usamos a função al_wait_for_event() na linha 83, que difere da função al_wait_for_event_until() já utilizada porque ela não recebe o timeout como último parâmetro. Isto quer dizer que o programa fica esperando até que o evento aconteça.

Na linha 86 testamos se o tipo do evento disparado é ALLEGRO_EVENT_MOUSE_AXES, que representa o movimento do mouse.

al_get_bitmap_width() e al_get_bitmap_height()

O if das linhas 88 à 91 testa se o ponteiro do mouse está entre as dimensões do bitmap maior, nas coordenadas X e Y. a função al_get_bitmap_width() serve para pegar a largura do bitmap e al_get_bitmap_height() a altura. Os campos mouse.x e mouse.y da variável ALLEGRO_EVENT acessam as posições X e Y do ponteiro do mouse, relativos à janela.

Na linha 99 testamos se o tipo do evento disparado é ALLEGRO_EVENT_MOUSE_BUTTON_UP, que representa o botão do mouse sendo soltado. Caso seja do desejo testar qual botão foi pressionado, usamos o campo mouse.button que possuirá os valores 1, 2 ou 3 para os botões esquerdo, direito e central, respectivamente. O if testa testa se o usuário ao clicar na janela, o cursor está dentro do espaço do bitmap menor. E em caso afirmativo seta a flag sair=1.

al_set_target_bitmap()

Após sair da repetição que verifica os eventos, na linha 113 chamamos a função al_set_target_bitmap() que muda o bitmap ativo para o bitmap area_central. Lembrando que as funções que fazem alterações em bitmaps (mudança de cor, desenho, etc) levam consideração sempre o bitmap ativo (por padrão o último display criado). Como já colorimos a janela com a cor preta na linha 109 e agora queremos colorir o bitmap area_central, devemos mudar o bitmap ativo. Por isso chamamos a função al_set_target_bitmap(). Em seguida colorimos ele na cor branca (R:255 G:255 B:255) ou na cor verde (R:0 G:255 B:0), dependendo do valor da flag na_area_central (que depende da posição do cursor do mouse, conforme vimos acima, na linha 92). Em seguida o mesmo é feito com o outro bitmap, o botao_sair.

al_get_backbuffer()

Na linha 126 queremos devolver o bitmap ativo para a janela, pois chegou o momento de escrever a area_central e botao_sair nela. Então chamamos a função al_set_target_bitmap(), mas ao invés de usar a janela como parâmetro, chamamos a função al_get_backbuffer(). E o porque disso será explicado.

Existem duas áreas de desenho da tela: O front buffer, e o back buffer. Quando criamos o display, automaticamente ele se torna o display ativo (isso já sabemos), e todas rotinas de desenho são feitas no back buffer desse display. O que está no front buffer é o que é mostrado na tela. Pontanto, ao usar a função al_flip_display(), o conteúdo do front e back buffer se inverte, fazendo com que mostremos o que antes estava no back buffer, por isso chamamos essa função de "função que atualiza a tela".

Com isso, percebemos que o bitmat ativo (aquele que desenhamos em cima) nunca deve ser o front buffer do display. Por conta disso, que quando mudamos o bitmap ativo de volta para a janela, precisamos mudar para o back buffer da janela, daí entra a função al_get_backbuffer().

Daí em diante no código é simples, desenhamos os dois bitmaps em posições diferentes da janela (no back buffer dela), e atualizamos a tela (trocando o front com o back buffer).

Outros links