Continuando nossa série de artigos traduzidos do site lazyfoo, veremos agora como lidar com gestos multi-toque na tela de um dispositivo móvel.
Nesse artigo, estaremos usando a funcionalidade embutida do SDL 2 para lidar com gestos multi-toque como arrastar e rotacionar.
//Scene textures LTexture gPinchCloseTexture; LTexture gPinchOpenTexture; LTexture gRotateTexture;
Como no artigo anterior, usaremos um conjunto de texturas para mostrar que tipo de evento está acontecendo.
//Main loop flag bool quit = false; //Event handler SDL_Event e; //Touch variables SDL_Point touchLocation = { gScreenRect.w / 2, gScreenRect.h / 2 }; LTexture* currentTexture = &gPinchOpenTexture;
Também como no artigo anterior, precisamos manter um registro do local onde o toque ocorreu e da textura a ser renderizada.
//Multi touch gesture else if( e.type == SDL_MULTIGESTURE ) { //Rotation detected if( fabs( e.mgesture.dTheta ) > 3.14 / 180.0 ) { touchLocation.x = e.mgesture.x * gScreenRect.w; touchLocation.y = e.mgesture.y * gScreenRect.h; currentTexture = &gRotateTexture; }
Quando um evento multi-toque acontece, um evento SDL_MultiGestureEvent é disparado. Aqui verificamos por rotações primeiro, checando pelo ângulo do gesto. O que é preciso lembrar aqui é que a menor rotação será reportada, assim se você arrastar e rotacionar por uma fração de radianos, irá mostrar o gesto. Aqui verificamos se a rotação é ao menos de 1 grau antes de reportar como uma rotação. Se a rotação for grande o suficiente, configuramos o local do gesto e a textura.
//Pinch detected else if( fabs( e.mgesture.dDist ) > 0.002 ) { touchLocation.x = e.mgesture.x * gScreenRect.w; touchLocation.y = e.mgesture.y * gScreenRect.h; //Pinch open if( e.mgesture.dDist > 0 ) { currentTexture = &gPinchOpenTexture; } //Pinch close else { currentTexture = &gPinchCloseTexture; } } }
Se a rotação não for grande o suficiente, verificamos que a distância do arrasto. Sempre lembre-se que as coordenadas são normalizadas, então um arrasto de 10 pixels em um tablet cuja resolução é 1920 pixels será reportada como 0.0052. Se o arrasto for grande o suficiente, configuramos a posição do gesto e então verificamos se o arrasto foi para abrir ou fechar.
//Clear screen SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF ); SDL_RenderClear( gRenderer ); //Render touch texture currentTexture->render( touchLocation.x - currentTexture->getWidth() / 2, touchLocation.y - currentTexture->getHeight() / 2 ); //Update screen SDL_RenderPresent( gRenderer );
Assim como no artigo anteror, na renderização mostramos a textura do gesto e a posição do gesto.
Baixe os arquivo de mídia e do código fonte desse artigo aqui.