Tutorial: Programando um jogo da memória – Parte 4: Identificação de pares e fim do jogo

Estamos quase terminando o desenvolvimento de mais um jogo.

Implementamos a escolha de um par de cartas e a animação das cartas girando.

Vamos terminar com a identificação de pares e checagem de término do jogo.

Vimos no último tutorial como implementar a escolha de duas cartas. Para que o jogador decidisse qual carta escolher, ele encostava nas duas cartas desejadas. Vimos que precisamos programar a animação da carta girando e a mudança do sprite frame no momento em que a carta era girada. Vimos também que tanto a primeira carta escolhida quanto a segunda precisavam ser giradas novamente, para que sejam mostrados os seus versos.

Nesse tutorial nós implementaremos a principal funcionalidade do jogo: a verificação se duas cartas escolhidas são iguais. Esse tutorial mostrará uma animação de retirada das cartas caso elas sejam iguais. Além disso, implementaremos também a checagem de término do jogo, que acontece quando o último par de cartas é escolhido.

Vale lembrar que vocês precisam finalizar por completo o tutorial passado. Iniciaremos com a edição do código existente no arquivo “HelloWorldScene.h”. Abra-o e adicione as seguintes linhas de código:

bool acerto;

void terminoJogo();

logo abaixo dessa:

int indiceCartaVirada2;

Apenas adicionamos uma variável nomeada “acerto” e um método nomeado “terminoJogo”. A variável armazena os valores verdadeiro e falso e possui a principal função de identificar se o jogador encontrou um par de cartas iguais. Caso isso aconteça, essa variável é igualada ao valor verdadeiro, caso contrário, ela é igualada ao valor falso. O método adicionado tem a principal função de identificar quando um par de cartas iguais escolhidas pelo jogador é o último par restante ou não. Além disso, caso seja o último par de cartas iguais, esse método mostra na tela uma etiqueta informando o término do jogo. Salve o arquivo “HelloWorldScene.h”.

Abra o arquivo “HelloWorldScene.cpp” e adicione as seguintes linhas de código:

if(HelloWorld::valorCartas[HelloWorld::indiceCartaVirada1]!=

  HelloWorld::valorCartas[HelloWorld::indiceCartaVirada2]) {

    HelloWorld::acerto = false;

logo abaixo dessa:

HelloWorld::indiceCartaVirada2 = carta;

Perto de onde você adicionou as últimas linhas de código, abaixo dessas linhas:

HelloWorld::cartas[HelloWorld::indiceCartaVirada1]->runAction(CCSequence::create(

  tempoVirarCarta1,primeiraMetade->copy(),viraCarta1,segundaMetade->copy(),telaDeToque,NULL));

adicione as seguintes linhas de código:

} else {

    HelloWorld::acerto = true;

    CCScaleTo* primeiraMetade = CCScaleTo::create(0.5,0.0,HelloWorld::cartas[HelloWorld::indiceCartaVirada1]->getScale());

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

    CCScaleTo* segundaMetade = CCScaleTo::create(0.5,HelloWorld::cartas[HelloWorld::indiceCartaVirada1]->getScale(),

    HelloWorld::cartas[HelloWorld::indiceCartaVirada1]->getScale());

    CCDelayTime* tempoChecagem = CCDelayTime::create(0.5);

    CCScaleTo* sumirCarta = CCScaleTo::create(0.5,0.0,0.0);

    HelloWorld::cartas[HelloWorld::indiceCartaVirada2]->runAction(CCSequence::create(

      primeiraMetade,mostraCarta2,segundaMetade,tempoChecagem,sumirCarta,NULL));

    CCDelayTime* tempoVirarCarta1 = CCDelayTime::create(1.5);

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

    CCCallFunc* telaDeToque = CCCallFunc::create(this,callfunc_selector(HelloWorld::acionaTelaDeToque));

    HelloWorld::cartas[HelloWorld::indiceCartaVirada1]->runAction(CCSequence::create(

      tempoVirarCarta1,sumirCarta->copy(),terminoJogo,telaDeToque,NULL));

}

Acabamos de incluir no algoritmo alguns trechos de código que identificam a ocorrência de dois casos: quando a primeira carta é igual à segunda e quando as duas são diferentes. Note que, quando as cartas são diferentes, o jogo fará exatamente o que implementamos no tutorial passado: girar a segunda carta escolhida e esconder as duas. Caso contrário, as cartas são iguais e outra animação é executada. Essa animação consiste em mostrar a segunda carta escolhida, e fazer as duas cartas desaparecerem da tela em meio segundo. Note que, caso o jogador escolha duas cartas diferentes, a variável “acerto” é igualada a falso e, caso contrário, ela é igualada a verdadeiro e o método “terminoJogo é chamado”.

O método “terminoJogo”, porém, ainda não foi implementado. Adicione no final do arquivo as seguintes linhas de código:

void HelloWorld::terminoJogo() {

    HelloWorld::valorCartas[HelloWorld::indiceCartaVirada1] = -1;

    HelloWorld::valorCartas[HelloWorld::indiceCartaVirada2] = -1;

    HelloWorld::indiceCartaVirada1 = -1;

    HelloWorld::indiceCartaVirada2 = -1;

    bool flag = true;

    for(int i=0;i<6;i++)

        if(HelloWorld::valorCartas[i]!=-1) {

            flag = false;

            break;

        }

    if(flag) {

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

        CCLabelTTF* fimDeJogo = CCLabelTTF::create(“Fim de jogo”,“”,50);

        fimDeJogo->setPosition(ccp(size.width/2,size.height/2));

        addChild(fimDeJogo);

    }

}

Note que, a cada par de cartas iguais, as suas posições no vetor “valorCartas” são igualadas ao valor -1. Isso porque precisamos identificar quais pares de cartas iguais já foram encontradas pelo jogador. Caso todas as posições do vetor “valorCartas” sejam iguais a -1, então todos os pares de cartas já foram encontrados e o jogo é finalizado, mostrando na tela uma etiqueta de fim de jogo. Por último, para que todas as animações ocorram com sucesso, adicione a seguinte linha de código:

if(HelloWorld::acerto==false)

logo abaixo dessas linhas:

HelloWorld::cartas[HelloWorld::indiceCartaVirada1]->setDisplayFrame(

  CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“CartaVirada.png”));

e logo abaixo dessas linhas também:

HelloWorld::cartas[HelloWorld::indiceCartaVirada2]->setDisplayFrame(

  CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“CartaVirada.png”));

Salve o arquivo “HelloWorldScene.cpp” e compile o código. Ao executar o jogo, você verá que, caso o jogador escolha duas cartas diferentes, os seus versos serão mostrados. Caso o jogador escolha duas cartas iguais, elas reduzirão de tamanho até desaparecerem. Caso as duas últimas cartas desaparecerem, o jogo mostra na tela uma etiqueta falando “Fim de jogo”. Para os curiosos de plantão, o jogo funciona exatamente como é mostrado no vídeo a seguir.

Vimos nesse tutorial como identificar se duas cartas são iguais ou não. Além disso, fizemos com que haja uma animação caso as cartas sejam iguais e haja outra animação caso sejam diferentes. Caso elas sejam iguais, o jogo reduz o tamanho delas gradativamente até elas desaparecerem. Também vimos como identificar um fim de jogo, que acontece quando o último par de cartas é encontrado pelo jogador.

Assim, terminamos mais um conjunto de tutoriais que geram um jogo clássico. No próximo tutorial, eu descreverei como podemos criar projetos de jogos para a plataforma Android com o motor gráfico Cocos2d-x mais atual. Eu já fiz um tutorial parecido mas, atualmente, ele se tornou obsoleto e é necessário atualizá-lo.

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