PUCRS/FACIN
Curso
de Especialização
em Desenvolvimento de Jogos
Digitais
Computação
Gráfica 2D
Profs.
Márcio Sarroglia Pinho
Isabel Harb Manssour
Colisão entre Sprites e Tiles
O objetivo desta aula é criar um programa que controle a colisão entre uma sprite e os tiles de uma cena.
Copie a última versão do Framework, disponível no Moodle.
Carregue o projeto no Visual Studio e abra o arquivo PlayState.cpp.
Colocando uma Moldura na Sprite
Para facilitar a visualização das colisões, vamos inicialmente desenhar uma moldura ao redor da sprite.
No final do método PlayState::draw, antes da chamada da função SDL_GL_SwapBuffers() coloque o trecho de código abaixo.
Observe como este código faz o desenho. Veja as coordenadas dos vértices.
Teste o programa.
// Desenha um box ao redor da sprite do cao
glColor3f(0,0,0);
glBegin(GL_LINE_LOOP);
glVertex2f(spriteCao->getX(), spriteCao->getY());
glVertex2f(spriteCao->getX()+spriteCao->getWidth(),spriteCao->getY());
glVertex2f(spriteCao->getX()+spriteCao->getWidth(),spriteCao->getY()+spriteCao->getHeight());
glVertex2f(spriteCao->getX(),spriteCao->getY()+spriteCao->getHeight());
glEnd();
glColor3f(1,1,1);
Controlando o movimento da sprite
No método PlayState::handleEvents(), após o final do while que faz o processamento dos eventos, coloque o código abaixo.
Este código controla o movimento da sprite na tela.
// verifica a tecla pressionada para atualizar as sprites
float salvaX, salvaY;
salvaX = spriteCao->getX();
salvaY = spriteCao->getY();
bool pressionou = false;
if (keystate[SDLK_UP]==1) {
cout << "Pra cima " << endl;
spriteCao->setY(spriteCao->getY()-1);
pressionou = true;
}
if (keystate[SDLK_DOWN]==1) {
cout << "Pra baixo " << endl;
spriteCao->setY(spriteCao->getY()+1);
pressionou = true;
}
if (keystate[SDLK_RIGHT]==1) {
cout << "Pra direita " << endl;
spriteCao->setX(spriteCao->getX()+1);
pressionou = true;
}
if (keystate[SDLK_LEFT]==1) {
cout << "Pra esquerda " << endl;
spriteCao->setX(spriteCao->getX()-1);
pressionou = true;
}
// testa colisão da sprite com o tile que contem o obstáculo
if (pressionou) {
if (TemColisaoSpriteTile(spriteCao, mapColisao)) {
spriteCao->setPosition(salvaX,salvaY);
}
pressionou = false;
}
Detectando a colisão da sprite com os tiles
Substituta o código do método PlayState::TemColisaoSpriteTile pelo trecho de código abaixo.
// método que testa se há colisão entre uma sprite e os elementos do tile
bool PlayState::TemColisaoSpriteTile(CSprite *sprite, CTilesMap *map) {
int nTile;
cout << "Posicao Sprite: " << sprite->getX() << "
" << sprite->getY() << endl;
//cout << "Largura do tile: " << map->getWidth() << endl;
cout << "Largura do sprite: " << sprite->getWidth() << endl;
int tileX, tileY;
tileX = sprite->getX() / map->getWidth();
tileY = sprite->getY() / map->getHeight() ;
cout << "Posicao do tile: [" << tileX << ", " << tileY << "] : " ;
nTile = map->getTileNumber(tileX, tileY);
cout << nTile << endl;
if (nTile == 192) // é fundo ??
return false;
else return true;
}
Exercício
Modifique o programa de forma a detectar a colisão nos quatro lados da sprite.
FIM.