Tutorial: Desenvolvendo um shoot em up game: Parte 6 – HUDs e término do jogo

E chegou o último tutorial sobre o desenvolvimento de um shoot em up.

Dessa vez, nós mostraremos a pontuação do jogador e a quantidade de vidas extras que ele tem.

Quando acabar as vidas, faremos com que o jogo seja finalizado.

 

Todos os tutoriais da sequência
Parte 1Parte 2Parte 3Parte 4Parte 5 – Parte 6

Vimos no último tutorial como adicionar os efeitos de explosão quando um tiro acerta alguma nave. Para isso, criamos duas listas que armazenam as referências dos sprites de tiro. Implementamos um método que verifica, a cada quadro, se houve colisão entre algum tiro e alguma nave. Caso isso aconteça, o jogo anima uma explosão quando ocorre colisão. Ao final, nós fizemos com que somente as naves que não foram explodidas pudessem atirar, inclusive a nave do próprio jogador.

Baloes_DKC3Nesse tutorial, nós implementaremos a última funcionalidade do nosso shoot em up. Incluiremos duas etiquetas de HUD na tela: uma que apresenta a quantidade de vidas restantes do jogador e uma que apesenta a quantidade de helicópteros que o jogador destruiu. Também implementaremos o término do jogo, fazendo ele parar a simulação quando o jogador perder a última vida indicando o jogador sobre o término do jogo por meio de um aviso em uma etiqueta. Partiu.

 

Somando pontos e HUD

Iniciaremos a implementação desse tutorial adicionando na classe “HelloWorld” duas novas variáveis que serão utilizadas no gerenciamento de pontos do jogo. Declararemos uma variável que armazena valores inteiros referentes à quantidade de helicópteros que o jogador já abateu e uma variável que armazena a referência de uma etiqueta que mostra esse valor na tela. Para declarar essas duas variáveis na classe “HelloWorld”, abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:

int pontos;

cocos2d::CCLabelTTF* etiquetaPontos;

logo abaixo dessa:

cocos2d::CCArray* tirosInimigos;

StartCom essas variáveis devidamente declaradas, agora poderemos utilizá-las a nosso favor. Obviamente, precisaremos inicializá-las antes do jogo começar a simulação. Então, armazenaremos a pontuação inicial do jogador, que é o valor numérico 0, e criaremos e adicionaremos na tela uma etiqueta que mostra essa pontuação ao jogador. Para isso, abra o arquivo “HelloWorldScene.cpp” e adicione as seguintes linhas de código:

HelloWorld::pontos = 0;

HelloWorld::etiquetaPontos = CCLabelTTF::create(“Pontos: 0”,“”,40);

HelloWorld::etiquetaPontos->setAnchorPoint(ccp(0,1));

HelloWorld::etiquetaPontos->setPosition(ccp(0,size.height/2));

HelloWorld::etiquetaPontos->setColor(ccc3(0,0,0));

addChild(HelloWorld::etiquetaPontos,3);

logo abaixo dessa:

addChild(HelloWorld::botaoTiro,3);

Adicionamos a etiqueta no lado esquerdo da tela, um pouco abaixo da região central. Agora precisaremos somar a pontuação do jogador quando um tiro disparado por ele acerta um helicóptero inimigo. Além disso, precisaremos atualizar a pontuação que é mostrada na tela conforme o valor somado na variável “pontos”. Para isso, adicione, no mesmo arquivo, as seguintes linhas de código:

char texto[16];

HelloWorld::pontos++;

sprintf(texto,“Pontos: %i”,HelloWorld::pontos);

HelloWorld::etiquetaPontos->setString(texto);

logo abaixo dessa:

explosao->runAction(CCSequence::create(anim,destruir,NULL));

A funcionalidade de soma de pontos do jogador já está devidamente implementada. Agora falta gerenciar as vidas do jogador e finalizar o jogo no momento correto.

 

Diminuindo vidas, HUD e finalização do game

contar-dedos-2Para que possamos contar corretamente as vidas perdidas pelo jogador, precisaremos declarar uma variável que armazena valores inteiros. Além dessa variável, precisaremos também de outra que armazena a referência da etiqueta que mostra na tela a quantidade de vidas do jogador. Para declarar essas variáveis na classe “HelloWorld”, abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:

int vidas;

cocos2d::CCLabelTTF* etiquetaVidas;

logo abaixo dessa:

cocos2d::CCLabelTTF* etiquetaPontos;

Como de praxe, cada variável recém-criada precisa ser inicializada. Inicializaremos a variável “vidas” com o valor numérico 5 e criaremos uma etiqueta que mostra a quantidade de vidas ao jogador. Para inicializarmos essas duas variáveis, abra o arquivo “HelloWorldScene.cpp” e adicione as seguintes linhas de código:

HelloWorld::vidas = 5;

HelloWorld::etiquetaVidas = CCLabelTTF::create(“Vidas: 5”,“”,40);

HelloWorld::etiquetaVidas->setAnchorPoint(ccp(0,0));

HelloWorld::etiquetaVidas->setPosition(ccp(0,size.height/2));

HelloWorld::etiquetaVidas->setColor(ccc3(0,0,0));

addChild(HelloWorld::etiquetaVidas,3);

logo abaixo dessa:

addChild(HelloWorld::etiquetaPontos,3);

Note que posicionamos essa etiqueta logo acima da etiqueta de HUD que mostra a pontuação do jogador. Agora, precisaremos reduzir o número de vidas do jogador toda vez que um tiro inimigo entra em contato com a nave do jogador. Além disso, precisaremos verificar se ainda não acabou a quantidade de vidas extras do jogador. Caso o jogador ainda tenha vidas, apenas atualizamos a etiqueta de vidas com a quantidade de vidas que ele ainda possui. Caso contrário, precisaremos finalizar a simulação e mostrar outra etiqueta na tela que informa o jogador sobre o término do jogo. Para isso, no mesmo arquivo, adicione as seguintes linhas de código:

HelloWorld::vidas–;

if(HelloWorld::vidas>=0) {

    char texto[9];

    sprintf(texto,“Vidas: %i”,HelloWorld::vidas);

    HelloWorld::etiquetaVidas->setString(texto);

} else {

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

    setTouchEnabled(false);

    unschedule(schedule_selector(HelloWorld::verificaColisaoTiros));

    unschedule(schedule_selector(HelloWorld::atiraInimigo));

    unschedule(schedule_selector(HelloWorld::entraInimigos));

    unschedule(schedule_selector(HelloWorld::saiInimigos));

    unschedule(schedule_selector(HelloWorld::criaTiroJogador));

    CCLabelTTF* fimDeJogo = CCLabelTTF::create(“Fim de Jogo”,“”,80);

    fimDeJogo->setPosition(ccp(size.width/2,HelloWorld::etiquetaPontos->getPositionY()-fimDeJogo->boundingBox().size.height));

    fimDeJogo->setColor(ccc3(0,0,0));

addChild(fimDeJogo,3);

}

logo abaixo dessa:

explosao->runAction(CCSequence::create(anim,destruir,aparecer,NULL));

Perceba que podem acontecer duas coisas após reduzir a quantidade de vidas: ou a quantidade de vidas é atualizada na tela, ou o jogo é finalizado e é informado esse acontecimento ao jogador. Agora sim, podemos dizer que finalizamos o desenvolvimento de mais um jogo para a nossa lista. Se você compilar o código e executar o aplicativo, acontecerá algo como o que é mostrado na Figura 1, quando o jogador perder todas as vidas.

Figura 1 - Jogo executando
Figura 1 – Jogo executando

 

Vimos nesse tutorial como incluir dois elementos de HUD: um contador de pontos e um contador regressivo de vidas. Também implementamos o término do jogo quando acabam as vidas do jogador. Fizemos mostrar na tela uma etiqueta que informa o fim do jogo caso não haja mais vidas após uma explosão da nave do jogador.

A minha próxima postagem não será sobre o início da implementação de outro jogo. Eu voltarei ao tópico de programação do Shark Pong, aquele jogo que a equipe do Fábrica de Jogos, em parceria com a equipe da Quasar Sound Work, desenvolveram praticamente do zero. Voltarei com a inclusão dos efeitos sonoros no jogo.

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