Continuando nossa série de artigos traduzido do site lazyfoo, dessa vez aproveitaremos o recurso de renderização de texturas acelerada por hardware do SDL para rotação e lançamento de imagens. Nesse artigo, usaremos esse recursos para fazer com que a textura de uma seta seja girada e lancada.
//Texture wrapper class class LTexture { public: //Initializes variables LTexture(); //Deallocates memory ~LTexture(); //Loads image at specified path bool loadFromFile( std::string path ); //Deallocates texture void free(); //Set color modulation void setColor( Uint8 red, Uint8 green, Uint8 blue ); //Set blending void setBlendMode( SDL_BlendMode blending ); //Set alpha modulation void setAlpha( Uint8 alpha ); //Renders texture at given point void render( int x, int y, SDL_Rect* clip = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE ); //Gets image dimensions int getWidth(); int getHeight(); private: //The actual hardware texture SDL_Texture* mTexture; //Image dimensions int mWidth; int mHeight; };
Aqui adicionamos mais funcionalidades à classe de textura. A função de renderização agora recebe um angulo de rotacão, um ponto para rotacionar a textura, e uma enumeração de lançamento do SDL.
Como no caso do recorte de retângulos, fornecemos valores padrão aos argumentos no caso de você querer renderizar a textura sem rotaciona-la ou lança-la.
void LTexture::render( int x, int y, SDL_Rect* clip, double angle, SDL_Point* center, SDL_RendererFlip flip ) { //Set rendering space and render to screen SDL_Rect renderQuad = { x, y, mWidth, mHeight }; //Set clip rendering dimensions if( clip != NULL ) { renderQuad.w = clip->w; renderQuad.h = clip->h; } //Render to screen SDL_RenderCopyEx( gRenderer, mTexture, clip, &renderQuad, angle, center, flip ); }
Como você pode ver, tudo que temos que fazer é passar nossos argumentos para nossa funcão SDL_RenderCopyEx. Esse função funciona de forma similar à função SDL_RenderCopy, mas com argumentos adicionais para rotação e lançamento.
//Main loop flag bool quit = false; //Event handler SDL_Event e; //Angle of rotation double degrees = 0; //Flip type SDL_RendererFlip flipType = SDL_FLIP_NONE;
Antes de entramos no loop principal, declaramos variáveis para manter registro do ângulo de rotação de tipo de lançamento.
//Handle events on queue while( SDL_PollEvent( &e ) != 0 ) { //User requests quit if( e.type == SDL_QUIT ) { quit = true; } else if( e.type == SDL_KEYDOWN ) { switch( e.key.keysym.sym ) { case SDLK_a: degrees -= 60; break; case SDLK_d: degrees += 60; break; case SDLK_q: flipType = SDL_FLIP_HORIZONTAL; break; case SDLK_w: flipType = SDL_FLIP_NONE; break; case SDLK_e: flipType = SDL_FLIP_VERTICAL; break; } } }
No loop de eventos, queremos aumentar ou diminuir a rotação com as teclas a e d e alterar o tipo de lançamento com as teclas q, w e e.
//Clear screen SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF ); SDL_RenderClear( gRenderer ); //Render arrow gArrowTexture.render( ( SCREEN_WIDTH - gArrowTexture.getWidth() ) / 2, ( SCREEN_HEIGHT - gArrowTexture.getHeight() ) / 2, NULL, degrees, NULL, flipType ); //Update screen SDL_RenderPresent( gRenderer );
Agora fazemos a renderização de fato. Primeiro informamos as coordenadas x e y. Essa pode parecer uma equação complicada, mas tudo o que é feito é achar o centro da imagem. Se a imagem tiver 440 pixels de largura em uma tela de 640 pixels de largura, queremos que a imagem seja fique com 100 pixels de cada lado. Em outras palavras, a coordenada x será a largura da tela (640) menos a largura da imagem (440) tudo dividido por 2 ( (640 – 440) / 2 = 100 ).
O argumento seguinte é o retângulo a ser recortado, e como estamos renderizando toda a textura seu valor será null. O argumento seguinte é o ângulo de rotação em graus. O argumento seguinte é ponto onde iremos rotacionar a imagem. Quando esse valor é null, iremos rotacionar a imagem em torno de seu centro. O último argumento é como a imagem será lancada.
A melhor maneira de entender como usar rotação é testa-la. Experimento para ver os tipos de efeito que você consegue combinando diferentes rotações e lançamentos.
Baixe os arquivo de mídia e código fonte desse artigo aqui.