Desenvolvendo um Jogo Digital do Zero: Parte 11 – Movimentando a pá do jogador

Já iniciamos a programação do Shark Pong.

Montamos a tela de gameplay, porém ainda não há interação com o jogo.

Hoje implementaremos a movimentação do surfista que o jogador tem controle. Bora.

Todas as partes da saga:

https://fabricadejogos.net/colunas/producao-jogo-digital-do-zero

Montamos no último artigo a tela e gameplay. Criamos o nosso sprite sheet e adicionamos os sprites do mar, dos dois surfistas, das conchas, do polvo e do tubarão. Nesse artigo, nós implementaremos a interação do jogador com o game. Faremos com que, se o jogador encoste na concha da esquerda, o surfista suba e, se o jogador encoste na concha da direita, o surfista desça.

Figura 1 - Versão atual do game

Figura 1 – Versão atual do game

Correção de erros

Mas, antes de tudo, arrumaremos um pequeno erro detectado no artigo passado. Vale falar que, durante o processo de desenvolvimento de um game, o jogo passa por modificações constantemente. Como a equipe é formada por humanos, logicamente, há erros que as vezes passam despercebidos. Note que os botões em forma de conchas estão invertidos em comparação com o que o Game Design Document mostra. Veja como está no GDD, mostrado na Figura 2 e veja como está até o momento na Figura 1. Obviamente, deve ser seguido o que está previsto no documento e uma correção se faz necessária.

Figura 2 - Versão prevista no GDD

Figura 2 – Versão prevista no GDD

Para arrumarmos isso, abra o arquivo “HelloWorldScene.cpp” e modifique a seguinte linha de código:

HelloWorld::botaoDescer->boundingBox().size.width/2,HelloWorld::botaoDescer->boundingBox().size.height/2));

de forma que ela fique assim:

size.width-HelloWorld::botaoDescer->boundingBox().size.width/2,HelloWorld::botaoDescer->boundingBox().size.height/2));

e a seguinte linha de código:

size.width-HelloWorld::botaoSubir->boundingBox().size.width/2,HelloWorld::botaoSubir->boundingBox().size.height/2));

de forma que ela fique assim:

HelloWorld::botaoSubir->boundingBox().size.width/2,HelloWorld::botaoSubir->boundingBox().size.height/2));

Essas modificações são suficientes para trocar os dois botões de lugar.

 

Implementação da movimentação da pá

Se vocês perceberem, eu me refiro constantemente ao surfista controlado pelo jogador como pá. Isso porque o nome no jogo oficial é esse. Então, quando eu referencio pá do jogador, por exemplo, significa o surfista controlado pelo jogador.

Se você é um programador um pouco mais experiente, perceberá que precisamos utilizar a tela de toque para podermos controlar o surfista. No Cocos2d-x, temos dois métodos principais que gerenciam isso: ccTouchesBegan e ccTouchesEnded.

O método ccTouchesBegan é chamado no momento que o jogador encosta o dedo na tela de toque, enquanto que o método ccTouchesEnded é chamado quando o dedo é desencostado. Dessa forma, precisaremos implementá-los.

Além disso, precisaremos da criação de uma variável que armazena o número identificador de um toque na tela. Isso porque precisamos saber quando o jogador desencosta o dedo do último botão apertado por ele. Assim, abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:

int idToque;

void ccTouchesBegan(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);

void ccTouchesEnded(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);

logo abaixo dessa:

cocos2d::CCSprite* botaoSubir;

Agora só falta acionar a tela de toque, inicializar a variável “idToque” e implementar os métodos. Salve o arquivo “HelloWorldScene.h” e abra o arquivo “HelloWorldScene.cpp”. Para acionar a tela de toque e inicializar a variável “idToque”, adicione as seguintes linhas de código do arquivo aberto recentemente:

HelloWorld::idToque = -1;

setTouchEnabled(true);

logo abaixo dessa:

addChild(HelloWorld::botaoSubir);

Falta poooouco. Para implementar os métodos ccTouchesBegan e ccTouchesEnded, adicione as seguintes linhas de código no final do arquivo:

void HelloWorld::ccTouchesBegan(CCSet *pTouches,CCEvent *pEvent) {

    CCSize size = CCDirector::sharedDirector()->getWinSize();

    float tempo;

    CCPoint ponto = (static_cast<CCTouch*>(pTouches->anyObject()))->getLocationInView();

    ponto.y = CCDirector::sharedDirector()->getWinSize().height – ponto.y;

    if(HelloWorld::botaoDescer->boundingBox().containsPoint(ponto)) {

        HelloWorld::paJogador->cleanup();

        HelloWorld::paJogador->setFlipY(true);

        tempo = abs(0.3*size.height – HelloWorld::paJogador->getPositionY())/300.0;

        HelloWorld::paJogador->runAction(CCMoveTo::create(tempo,ccp(HelloWorld::paJogador->getPositionX(),0.3*size.height)));

        HelloWorld::idToque = (static_cast<CCTouch*>(pTouches->anyObject()))->getID();

    } else if(HelloWorld::botaoSubir->boundingBox().containsPoint(ponto)) {

        HelloWorld::paJogador->cleanup();

        HelloWorld::paJogador->setFlipY(false);

        tempo = abs(0.9*size.height – HelloWorld::paJogador->getPositionY())/300.0;

        HelloWorld::paJogador->runAction(CCMoveTo::create(tempo,ccp(HelloWorld::paJogador->getPositionX(),0.9*size.height)));

        HelloWorld::idToque = (static_cast<CCTouch*>(pTouches->anyObject()))->getID();

    }

}

void HelloWorld::ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent) {

    if(HelloWorld::idToque==(static_cast<CCTouch*>(pTouches->anyObject()))->getID())

        HelloWorld::paJogador->cleanup();

}

Se você for analisar o código, perceberá que, primeiramente, identificamos em qual botão o jogador clicou. Caso ele clicou na concha que faz a pá subir, nós paramos qualquer movimento ou animação do surfista, calculamos o tempo necessário para ele subir até a parte superior da tela, o fazemos se movimentar até lá e armazenamos o número identificador do toque.

Fazemos algo parecido caso o jogador clique na concha que faz a pá descer, mas, obviamente, mudamos o sentido do movimento. Caso o jogador tire o dedo da tela, primeiramente, é verificado se ele parou de apertar o último botão que ele clicou. Caso isso aconteça, nós paramos a movimentação no surfista. O resultado é algo parecido com o que é mostrado na animação a seguir:

Vimos nesse artigo como incluir a interação do jogador com a pá do Shark Pong. Precisamos adicionar uma variável que armazena o número identificador do toque na tela e implementar duas funções de toque.

Fizemos com que o surfista andasse de acordo com o botão apertado e o fazemos parar de se movimentar caso o jogador tire o dedo da tela. Além disso, também arrumamos um pequeno erro de programação que foi a troca de lugares dos dois botões em forma de concha.

No próximo artigo, nós programaremos o movimento do tubarão pelo mar, além do sistema de detecção e resposta de colisão da barbatana dele com as pranchas dos surfistas.

Um grande abraço e até mais. []

Santiago Viertel

Santiago Viertel

Formado em Bacharelado em Ciência da Computação (UDESC), mestre e doutorando em Análise de Algoritmos (UFPR). Foi programador da Céu Games por 8 anos. Possui a preferência por jogos de estratégia e de tiro em primeira pessoa. Jogando bastante DotA 2, Left 4 Dead 2 e Age of Empires II HD.

Send this to a friend