Continuando nossa série de artigo traduzidos do site lazyfoo, agora veremos como rolar a tela para navegar por uma imagem cujo tamanho é maior do que a área visível.
//The dimensions of the level const int LEVEL_WIDTH = 1280; const int LEVEL_HEIGHT = 960; //Screen dimension constants const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480;
Como o nível não é mais do tamanho da tela temos que ter um conjunto separado de constantes para definir o tamanho do nível.
//The dot that will move around on the screen class Dot { public: //The dimensions of the dot static const int DOT_WIDTH = 20; static const int DOT_HEIGHT = 20; //Maximum axis velocity of the dot static const int DOT_VEL = 10; //Initializes the variables Dot(); //Takes key presses and adjusts the dot's velocity void handleEvent( SDL_Event& e ); //Moves the dot void move(); //Shows the dot on the screen relative to the camera void render( int camX, int camY ); //Position accessors int getPosX(); int getPosY(); private: //The X and Y offsets of the dot int mPosX, mPosY; //The velocity of the dot int mVelX, mVelY; };
Dessa vez o ponto tem que ser renderizado relativamente à câmera, assim sua função de renderização recebe a posição da câmera.
void Dot::move() { //Move the dot left or right mPosX += mVelX; //If the dot went too far to the left or right if( ( mPosX < 0 ) || ( mPosX + DOT_WIDTH > LEVEL_WIDTH ) ) { //Move back mPosX -= mVelX; } //Move the dot up or down mPosY += mVelY; //If the dot went too far up or down if( ( mPosY < 0 ) || ( mPosY + DOT_HEIGHT > LEVEL_HEIGHT ) ) { //Move back mPosY -= mVelY; } }
Dessa vez quando movemos o ponto, verificamos se o ponto se moveu para fora do nível ao contrário de checar se ele se moveu para fora da tela, já que a tela irá se mover em torno do nível.
void Dot::render( int camX, int camY ) { //Show the dot relative to the camera gDotTexture.render( mPosX - camX, mPosY - camY ); }
Agora quando renderizarmos objetos na tela, renderizaremos ele relativamente à câmera, pela subtração do deslocamento da câmera.
//Main loop flag bool quit = false; //Event handler SDL_Event e; //The dot that will be moving around on the screen Dot dot; //The camera area SDL_Rect camera = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
Antes de entrarmos no loop principal, declaramos o ponto e a câmera que iremos seguir.
//Move the dot dot.move(); //Center the camera over the dot camera.x = ( dot.getPosX() + Dot::DOT_WIDTH / 2 ) - SCREEN_WIDTH / 2; camera.y = ( dot.getPosY() + Dot::DOT_HEIGHT / 2 ) - SCREEN_HEIGHT / 2; //Keep the camera in bounds if( camera.x < 0 ) { camera.x = 0; } if( camera.y < 0 ) { camera.y = 0; } if( camera.x > LEVEL_WIDTH - camera.w ) { camera.x = LEVEL_WIDTH - camera.w; } if( camera.y > LEVEL_HEIGHT - camera.h ) { camera.y = LEVEL_HEIGHT - camera.h; }
Depois que movemos o ponto, queremos alterar a posição da câmera para centralizá-la em torno do ponto. Não queremos que a câmera vá para fora do nível, então mantemos ele nos limites depois de movê-la.
//Clear screen SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF ); SDL_RenderClear( gRenderer ); //Render background gBGTexture.render( 0, 0, &camera ); //Render objects dot.render( camera.x, camera.y ); //Update screen SDL_RenderPresent( gRenderer );
Baixe os arquivo de mídia e o código fonte sesse artigo aqui.