Olá pessoal! Esta é a terceira lição do SDL 2. As informações são obtidas 
dessa fonte. Não gostei dos tutoriais de manipulação de eventos do Lasy Foo, por isso vou escrever os meus, mas o material pode ser encontrado 
aqui e 
aqui .
E começamos, bem-vindo à lição
Eventos
Hoje ensinaremos nosso programa a responder a eventos com a ajuda de 
John .
Então, vamos começar. conecte o SDL 2 e crie 3 variáveis globais e 2 constantes.
#include <SDL2/SDL.h> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *john = NULL; 
Em seguida, escrevemos 3 funções já conhecidas da última lição:
Init int init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init: " << SDL_GetError() << std::endl; system("pause"); return 1; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; system("pause"); return 1; } scr = SDL_GetWindowSurface(win); return 0; } 
 Carregar int load() { john = SDL_LoadBMP("john.bmp"); if (john == NULL) { std::cout << "Can't load image: " << SDL_GetError() << std::endl; system("pause"); return 1; } return 0; } 
 Sair int quit() { SDL_FreeSurface(john); SDL_DestroyWindow(win); SDL_Quit(); return 0; } 
 Atenção (!), Se você copiar o código da lição anterior, não esqueça de mudar o 
sorriso para 
john .
Tudo isso deve ser dito: eu decidi mostrar erros no estágio de inicialização e carregamento de imagens.
Então, vamos continuar. abra 
main e chame as funções 
Init e 
Load .
 int main (int argc, char ** args) { if (init() == 1) { return 1; } if (load() == 1) { return 1; } } 
Agora vamos ver como funciona qualquer aplicativo. Qualquer programa que você executa (Google Chrome, Paint, Minecraft) tem um loop principal que é executado inúmeras vezes. Isso é necessário para o dinamismo. Anteriormente, escrevemos um programa que apenas mostrava um sorriso por 2 segundos, mas para que o programa aprenda a responder às ações do usuário (ou pelo menos exibir a imagem infinitamente), ele precisa de um loop 
While .
Ele será repetido constantemente e nele já podemos fazer o que queremos, por exemplo, processar eventos. Mas antes de iniciar o ciclo da glande, vamos criar algumas variáveis.
  bool run = true; SDL_Event e; SDL_Rect r; int x = 0; int y = 0; rx = x; ry = y; 
Vamos analisar tudo agora. Primeiro, crie uma variável de 
execução do tipo 
booleano . Essa variável é responsável pela execução do loop: enquanto o programa está em execução, é 
verdade , se queremos parar a execução, defina essa variável como 
false . Em seguida, crie um objeto 
e da classe 
SDL_Event . As propriedades deste objeto conterão os dados do evento recebido, mais detalhados. Depois disso, criamos um objeto 
r da classe 
SDL_Rect . Este é o retângulo necessário para desenhar o objeto com algumas coordenadas necessárias. Em seguida, criamos as variáveis 
xey do tipo 
int . Atribua imediatamente seus valores a zero. Essas serão as coordenadas do nosso personagem. No próximo item, atribuímos as variáveis 
rx e 
ry aos valores 
x e 
y, respectivamente. 
rx e 
ry são as coordenadas do retângulo 
r .
É hora de abrir o ciclo principal.
  while (run) { while(SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { run = false; } if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_UP) { y -= 1; } if (e.key.keysym.sym == SDLK_DOWN) { y += 1; } if (e.key.keysym.sym == SDLK_RIGHT) { x += 1; } if (e.key.keysym.sym == SDLK_LEFT) { x -= 1; } } } rx = x; ry = y; SDL_FillRect(scr, NULL, SDL_MapRGB(scr -> format, 255, 255, 255)); SDL_BlitSurface(john, NULL, scr, &r); SDL_UpdateWindowSurface(win); } 
Vamos analisar esse código. Nós temos dois ciclos. O primeiro principal é o principal, que funciona executando a variável, como mencionado anteriormente. O segundo loop é responsável por manipular eventos.
A função 
SDL_PollEvent () abre a fila de eventos recebidos em uma execução do loop principal, exclui o último evento e grava dados sobre esse evento nas variáveis do objeto que passamos para essa função, temos este 
e . Esta função retorna 0, 
NULL ou 
false se todos os eventos da fila foram excluídos, portanto, escrevemos a condição 
while (SDL_PollEvent (& e)! = NULL) .
Nós olhamos além: a primeira verificação que temos é clicar na cruz na moldura da janela. Se 
clicarmos nele, a variável de 
tipo do objeto 
e receberá o valor 
SDL_QUIT . Se isso acontecer, atribuímos 
false à variável 
run e o loop termina.
Em seguida, escrevi um teste de pressionamento de tecla do teclado. Se o botão for pressionado, a variável 
e.type será igual a 
SDL_KEYDOWN . Em seguida, verifique os valores-chave. a variável 
e.key.keysym.sym armazena o valor do botão. Comparamos esse valor com o desejado e executamos determinadas ações. Mudaremos a coordenada de John. Se a seta para cima é pressionada, 
y diminui em 1, se para baixo, aumenta etc. O ponto, eu acho, você entende.
Após processar os eventos, reatribua 
rx e 
ry para atualizar as coordenadas do Homem. Em seguida, escrevemos a função já familiar 
SDL_FilRect , que tem um papel muito grande. Se não o tivéssemos escrito, John teria deixado um traço feio ao se mover, e assim, em cada quadro, desenhamos um fundo branco e desenhamos um sprite em cima dele. Depois disso, desenhamos nosso herói com a função 
SDL_BlitSurface . Aqui, usaremos nosso retângulo 
r , ou melhor, suas variáveis 
x e 
y , para desenhar não apenas no canto superior esquerdo, mas com algumas coordenadas necessárias. Em seguida, basta atualizar a janela.
Após o loop principal, escreva 
return quit (); para completar o programa.
Isso é tudo, esta lição acabou. Aqui está um código:
Código #include <SDL2/SDL.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *john = NULL; int init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init: " << SDL_GetError() << std::endl; system("pause"); return 1; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; system("pause"); return 1; } scr = SDL_GetWindowSurface(win); return 0; } int load() { john = SDL_LoadBMP("john.bmp"); if (john == NULL) { std::cout << "Can't load image: " << SDL_GetError() << std::endl; system("pause"); return 1; } return 0; } int quit() { SDL_FreeSurface(john); SDL_DestroyWindow(win); SDL_Quit(); return 0; } int main (int argc, char ** args) { if (init() == 1) { return 1; } if (load() == 1) { return 1; } bool run = true; SDL_Event e; SDL_Rect r; int x = 0; int y = 0; rx = x; ry = y; while (run) { while(SDL_PollEvent(&e) != NULL) { if (e.type == SDL_QUIT) { run = false; } if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_UP) { y -= 1; } if (e.key.keysym.sym == SDLK_DOWN) { y += 1; } if (e.key.keysym.sym == SDLK_RIGHT) { x += 1; } if (e.key.keysym.sym == SDLK_LEFT) { x -= 1; } } } rx = x; ry = y; SDL_FillRect(scr, NULL, SDL_MapRGB(scr -> format, 255, 255, 255)); SDL_BlitSurface(john, NULL, scr, &r); SDL_UpdateWindowSurface(win); } return quit(); } 
 E eu digo adeus a você, tchau a todos!
<< Lição anterior || Próxima lição 
>>