Tutorial: Desenvolvendo um jogo de memorização de sinais: Parte 4 – Fluxo do jogo

Voltamos à implementação do jogo de memorização de sequências de sinais.

Já programamos as funcionalidades de criação e apresentação da sequência de sinais, assim como a interação com o jogo.

Daremos continuidade com a programação do fluxo do jogo.

 

Parte 1Parte 2Parte 3 – Parte 4 – Parte 5

Revisando a Construção do Nosso Jogo de Memorização de Sinais

Com minha participação, a última postagem no blog não foi referente a esse conjunto de tutoriais e sim quanto a finalização da implementação do Shark Pong, aquele jogo desenvolvido praticamente do zero. Veja toda a saga aqui.

Dando sequencia aos trabalhos, quanto no último tutorial referente a essa série, nós vimos como adicionar interação no jogo. Fizemos com que a lâmpada referente ao botão apertado pelo jogador acenda, caso ele clique no seu respectivo botão. Além disso, fizemos com que a mesma apagasse quando o jogador tirava o dedo da tela. Isso faz com que a lâmpada fique acesa exatamente enquanto o jogador esteja apertando o botão correspondente a ela.

lampadaNesse tutorial nós implementaremos o fluxo do jogo. Mas como funciona isso? Ele segue a seguinte lógica: o computador mostra a sequência de sinais, depois o jogador a informa por meio dos botões na tela. Essa lógica continua até que o jogador erra a sequência e o jogo é finalizado.

Vamos dividir o tutorial de hoje em: vez do computador e vez do jogador.

 

Vez do computador

Começaremos a edição do código declarando na classe “HelloWorld” os métodos especializados por fazer a transição entre a vez do computador apresentar a sequência e a vez do jogador apresentá-la. Abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:

void vezDoComputador();

void vezDoJogador();

logo abaixo dessa:

int idToque;

Após as declarações, vamos começar implementando o método “vezDoComputador”. Abra o arquivo “HelloWorldScene.cpp” e adicione as seguintes linhas de código no final do arquivo.

void HelloWorld::vezDoComputador() {

    setTouchEnabled(false);

    HelloWorld::aumentaSequencia();

    HelloWorld::mostraSequencia();

}

Note que é simples o procedimento necessário para fazer o jogador aumentar a sequência de sinais e apresentá-la na tela. Inicialmente, se impossibilita o jogador de fazer qualquer interação com o jogo desabilitando a tela de toque. Após isso, fazemos a sequência ser aumentada com um sinal a mais no final e, por último, apresentamos a sequência ao jogador.

largadaCom o método “vezDoComputador” implementado, agora podemos dar o início correto ao jogo. Para fazer acontecer, basta chamar esse método logo após todas as inicializações do jogo. Para isso, apague a seguinte linha de código do arquivo “HelloWorldScene.cpp”:

setTouchEnabled(true);

e, nesse mesmo lugar, adicione a seguinte linha de código:

HelloWorld::vezDoComputador();

Após a sequência ter sido ampliada e apresentada ao jogador, precisamos fazer a transição para o jogo esperar a entrada do jogador. Note que é indispensável acionar a tela de toque para que o jogador possa entrar com a sequência. Na verdade, essa é, praticamente, a única necessidade nesse momento. Assim, vamos iniciar a inclusão dessa funcionalidade com a implementação do método “vezDoJogador”. Adicione as seguintes linhas de código no final do arquivo.

void HelloWorld::vezDoJogador() {

    setTouchEnabled(true);

}

Para que a tela de toque seja acionada no momento correto, adicione as seguintes linhas de código:

CCDelayTime* tempoJogador = CCDelayTime::create(0.6*(1+HelloWorld::sequencia->count()));

CCCallFunc* chamadaVezDoJogador = CCCallFunc::create(this,callfunc_selector(HelloWorld::vezDoJogador));

CCSequence* seqFim = CCSequence::create(tempoJogador,chamadaVezDoJogador,NULL);

runAction(seqFim);

logo abaixo dessa:

HelloWorld::lampDir->runAction(CCSequence::create(seq4));

Se você analisar esse último código adicionado, perceberá que fizemos o jogo esperar a quantidade exata de tempo necessário para apresentar toda a sequência e, somente após isso, chamamos o método “vezDoJogador”.

Acabamos de incluir a transição entre a apresentação da sequência e a entrada do jogador.

 

Vez do jogador

myturnPensando na vez do jogador, nós precisamos identificar quantos botões o jogador já acertou. Isso é importante porque é necessário identificar em qual momento da sequência o jogador se encontra. Assim sendo, precisamos declarar uma variável na classe “HelloWorld” para que isso funcione. Abra o arquivo “HelloWorldScene.h” e adicione a seguinte linha de código:

int conta;

logo abaixo dessa:

int idToque;

Essa variável precisa armazenar zero toda vez que o jogo aumenta em um sinal a mais na sequência. Assim, toda vez que o jogador apresentar a sequência novamente, ela é validada desde o início. Para zerar a variável “conta” no momento correto, abra o arquivo “HelloWorldScene.cpp” e adicione a seguinte linha de código:

HelloWorld::conta = 0;

logo abaixo dessa:

void HelloWorld::vezDoComputador() {

Agora nós precisamos validar cada entrada do jogador com cada elemento da sequência. Isso gerará uma série de mudanças no método “ccTouchesBegan”. Antes de tudo, vamos capturar qual é o próximo sinal da sequência. Adicione a seguinte linha de código:

int v = (static_cast<CCInteger*>(HelloWorld::sequencia->objectAtIndex(HelloWorld::conta)))->getValue();

logo abaixo dessa:

ponto.y = size.height – ponto.y;

Para verificar se o jogador clicou no botão correto, adicione a seguinte linha de código:

if(v==0) {

logo abaixo dessa:

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

, adicione a seguinte linha de código:

if(v==1) {

logo abaixo dessa:

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

, adicione a seguinte linha de código:

if(v==2) {

logo abaixo dessa:

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

e adicione a seguinte linha de código:

if(v==3) {

logo abaixo dessa:

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

fecharportaProgramadores mais experientes notarão que nós abrimos uma estrutura de seleção em cada uma dessas linhas recentemente adicionadas e não fechamos nenhuma. Precisamos fechar cada uma delas para que o jogo funcione corretamente. Para fazer isso, adicione as seguintes linhas de código:

    HelloWorld::conta++;

} else {

    HelloWorld::menuCloseCallback(this);

}

logo abaixo dessas:

HelloWorld::lampSup->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“LuzAcesa.png”));

HelloWorld::idToque = (static_cast<CCTouch*>(touches[0]))->getID();

, dessas:

HelloWorld::lampInf->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“LuzAcesa.png”));

HelloWorld::idToque = (static_cast<CCTouch*>(touches[0]))->getID();

, dessas:

HelloWorld::lampEsq->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“LuzAcesa.png”));

HelloWorld::idToque = (static_cast<CCTouch*>(touches[0]))->getID();

e dessas:

HelloWorld::lampDir->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“LuzAcesa.png”));

HelloWorld::idToque = (static_cast<CCTouch*>(touches[0]))->getID();

Note que, se o jogador aperta o botão correto, a respectiva lâmpada é acesa e a variável “conta” é incrementada, para que, na próxima vez, seja validado o próximo sinal da sequência. Caso o jogador aperte em um botão errado, então o jogo é finalizado. Não nos preocupamos com HUD nem com término de jogo ainda já que esse é o tema do próximo tutorial.

Para finalizar o tutorial de hoje, só falta fazer a transição do término da vez do jogador para a apresentação da sequência aumentada. O momento de fazer tal transição é quando o jogador tira o dedo da tela, após apertar o último botão da sequência. Assim, adicione as seguintes linhas de código:

if(HelloWorld::conta==HelloWorld::sequencia->count()) {

    HelloWorld::vezDoComputador();

}

logo abaixo dessas:

HelloWorld::lampDir->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“LuzApagada.png”));

HelloWorld::idToque = -1;

contadordinheiroA ideia é simples: caso a variável “conta” for igual ao tamanho do vetor que armazena a sequência, então o jogador terminou de apresentar o último botão. Quando isso acontece, o jogo faz a transição para o computador apresentar a sequência aumentada. Pronto, o fluxo do jogo está devidamente implementado.
Vimos nesse tutorial como implementar o fluxo do jogo de memorização de sequência de sinais. Tivemos que dividir a execução do jogo em duas partes: uma que mostra a sequência de sinais ao jogador e outra em que o jogador apresenta a sequência ao jogo.

No próximo tutorial, nós adicionaremos os elementos de HUD, para deixar o jogo mais intuitivo. Além disso, nós implementaremos o término do jogo apresentando ao jogador até onde ele conseguiu decorar a sequência.

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

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.