Tutorial SDL [Artigo] - página 4
Eventos no SDL
Para ler eventos, usaremos uma função chamada SDL_PollEvent, que lerá a fila de eventos e colocará o mais antigo numa variável SDL_Event.
Internamente, o SDL enfileira os eventos e a cada chamada de SDL_PollEvent, será posto numa variável SDL_Event, o evento mais antigo e assim poderá ser processado da maneira que quisermos.
O próximo programa mostrará como fechar a janela principal, esse programa servirá de base para os próximos.
Arquivo: eventos_01.c
gcc -o eventos_01 eventos_01.c -lSDL
SDL_Event event; :: variável para tratar os eventos. SDL_Event é a estrutura de todos os eventos do SDL. Tem dois usos específicos: ler eventos da fila de eventos e colocar evento na fila de eventos. Por enquanto, apenas ler os evento é o bastante. Há duas funções que leem eventos, que são: SDL_PollEvent e SDL_PeepEvetns. Mas vamos usar somente SDL_PollEvent.
while (SDL_PollEvent(&event)) :: aqui estamos lendo toda a fila de eventos. Esse é o motivo de usar um while, se usássemos um if, apenas um evento seria lido (o mais antigo, é claro). Enquanto houver eventos na fila SDL_PollEvent, retornará 1, se não houver retorna 0. Ele recebe um ponteiro para um SDL_Event que será preenchido com o evento mais antigo da fila de eventos.
if (event.type == SDL_QUIT) :: verifica se o evento atual lido da fila de eventos é do tipo SDL_QUIT. Esse evento é chamado assim que o usuário clica sobre o botão fechar da janela.
1. Movimento do mouse:
Arquivo: eventos_02.c
// Verifica se o evento mais antigo é do tipo SDL_MOUSEMOTION
if (event.type == SDL_MOUSEMOTION) // Se o usuário moveu o cursor sobre a tela
printf("Moveu o cursor para X = %d, Y = %d\n", event.motion.x, event.motion.y);
gcc -o eventos_02 eventos_02.c -lSDL
if (event.type == SDL_MOUSEMOTION) :: verifica se o tipo de evento é SDL_MOUSEMOTION (movimento do mouse). Esse tipo de evento só é identificado se o cursor estiver sobre a janela principal. Fora dela, mesmo com movimento do mouse, nenhum evento é disparado.
Poderia alterar o programa para colocar uma imagem sob o ponteiro do mouse. Bastava apenas criar uma variável SDL_Rect com nome dest e setar as coordenadas para a posição do cursor. Veja abaixo:
Arquivo: eventos_03.c
SDL_Rect dest; // Destino da imagem dentro do screen
image = SDL_LoadBMP("ball.bmp"); // Carrega o arquivo de imagem
// Verifica se carregou a imagem
while (SDL_PollEvent(&event)) // Lê a fila de eventos e põe o evento mais antigo em "event"
// Seta o destino da imagem para as coordenadas do cursor
dest.x = event.motion.x; // Posição do cursor no eixo X
dest.y = event.motion.y; // Posição do cursor no eixo Y
SDL_BlitSurface(image, NULL, screen, &dest); // Joga a imagem no "screen" em "dest"
gcc -o eventos_03 eventos_03.c -lSDL
Se você apagar a linha com SDL_FillRect(screen, NULL, 0x0); poderá ver o por quê de ter que pintar todo o screen com uma cor antes de "blitar" uma imagem. A tela ficará toda "suja" com blitagem passadas de "image". Fica parecendo até bug do Windows. (rsrs)
2. Botão do mouse:
Arquivo: eventos_04.c
// Verifica se o evento mais antigo é do tipo SDL_MOUSEBUTTONDOWN
if (event.type == SDL_MOUSEBUTTONDOWN) // Se o usuário clicou
printf("APERTOU o botão do mouse: botão ESQUERDO\n");
printf("APERTOU o botão do mouse: botão DIREITO\n");
// Verifica se o evento mais antigo é do tipo SDL_MOUSEBUTTONUP
if (event.type == SDL_MOUSEBUTTONUP) // Se o usuário clicou
printf("SOLTOU o botão do mouse: botão ESQUERDO\n");
printf("SOLTOU o botão do mouse: botão DIREITO\n");
gcc -o eventos_04 eventos_04.c -lSDL
if (event.type == SDL_MOUSEBUTTONDOWN) :: verifica se apertou um botão do mouse.
if (event.type == SDL_MOUSEBUTTONUP) :: verifica se soltou um botão do mouse. Em event o botão pressionado ou solto fica armazenado em button que é do tipo SDL_MouseButtonEvent. Essa estrutura contém outros membros como posição do clique (x e y) e estado do botão (state).
Exercício: colocar uma imagem na posição onde o usuário clicar. Use man SDL_MouseButtonEvent, para mais informação.
Manipulando o teclado
1. Evento de pressionar e soltar de tecla:
Arquivo: eventos_05.c
printf("APERTOU uma tecla\n");
// Verifica se o evento mais antigo é do tipo SDL_KEYUP
printf("SOLTOU uma tecla\n");
gcc -o eventos_05 eventos_05.c -lSDL
if (event.type == SDL_KEYDOWN) :: verifica se o usuário apertou uma tecla do teclado.
if (event.type == SDL_KEYUP) :: verifica se o usuário soltou uma tecla do teclado. O teclado só produz esses dois tipos de eventos.
2. Identificando teclas pressionada ou solta:
Arquivo: eventos_06.c
printf("APERTOU uma tecla: ");
printf("Seta para CIMA\n");
printf("Seta para BAIXO\n"):
printf("Seta DIREITA\n");
printf("Seta ESQUERDA\n");
printf("SOLTOU uma tecla: ");
gcc -o eventos_06 eventos_06.c -lSDL
switch (event.key.keysym.sym) case SDLK_UP:
Aqui estamos verificando qual tecla foi apertada/solta. Dessa vez, a estrutura das tecla é um pouco mais longa, event.key.keysym.sym é preciso acessar duas estruturas para saber o código/símbolo da tecla apertada/solta.
Todo símbolo de tecla no SDL começa com SDLK_ seguida da tecla. Então, se, por exemplo, quisermos a tecla a use SDLK_a, tecla b use SDLK_b e assim por diante.
Mas, há teclas que não seguem esse padrão, as teclas do teclado numérico, por exemplo, use SDLK_KP_"número da tecla". Para saber sobre todos os símbolos, use man SDLKey no terminal.