Tutorial: Criando um jogo ao estilo Arkanoid – Parte 6: Adicionando elementos de HUD

Estamos encaminhando para o final de mais um conjunto de tutoriais voltados ao desenvolvimento de um game.

A única coisa que está faltando nesse momento é adicionarmos os elementos que dão feedback sobre o desempenho do jogador.

Partiu finalizar o desenvolvimento de mais um jogo.

No tutorial passado nós incluímos a funcionalidade de destruir os blocos amarelos, o que nos proporcionou adicionar um objetivo ao jogo. Vimos que não basta apenas destruir os blocos, mas também tivemos que identificar qual seria o bloco a ser destruído e como a bola de fogo é rebatida. Para isso, realizamos a detecção de colisão entre a bola de fogo e os blocos amarelos seguida da resposta da colisão, que identificava o bloco mais próximo com colisão, retirava-o da tela e rebatia a bola de fogo. Nesse tutorial não implementaremos novas funcionalidades no nosso Arkanoid, mas incluiremos itens que são indispensáveis em qualquer jogo: as HUDs.

Começo o tutorial fazendo a seguinte pergunta a vocês, fiéis leitores. Quais são os elementos que mostrariam o desempenho que o jogador está tendo no jogo? Eu só consigo pensar em dois nesse momento, um indicador de quantos blocos foram quebrados e outro de quantas vezes o jogador deixou a bola de fogo sair da tela. Vamos eliminar o tempo de jogo para esse game. =]

Para que isso seja possível, precisamos de uma variável para armazenar a quantidade de blocos que já foram quebrados e outra para armazenar a quantidade de vezes que o jogador deixou a bola de fogo sair da tela. Não obstante, precisamos também de duas etiquetas na tela para mostrar esses indicadores ao jogador. Nota-se que essas etiquetas poderão sofrer mudanças durante o jogo, isso porque ele inicia mostrando um valor para o jogador e termina mostrando outro. Dessa forma, precisamos criar uma referência dessas etiquetas na classe HelloWorld, para que possamos modificá-las no meio do jogo, bem como precisamos incluir as variáveis que armazenam as quantidades de blocos quebrados e de vezes que o jogador deixou a bola sair.

Vamos ao código. Ainda é preciso lembrar que é necessário fazer o último tutorial? Abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:

int pontos;

int chances;

cocos2d::CCLabelTTF* etiquetaDePontos;

cocos2d::CCLabelTTF* etiquetaDeChances;

logo abaixo dessa:

float vetorDirecao[2];
labelNote que incluímos duas variáveis: uma chamada “pontos”, que armazena a quantidade de blocos já destruídos e outra chamada “chances”, que armazena a quantidade de vezes que o jogador deixou a bola de fogo sair da tela. Note que também adicionamos as referências de outras duas variáveis de etiqueta, uma chamada “etiquetaDePontos”, que referencia a etiqueta que mostra a quantidade de blocos já destruídos e outra chamada “etiquetaDeChances” que mostra a quantidade de vezes que a bola de fogo saiu.

Primeiramente vamos inicializar os valores das duas variáveis “pontos” e “chances” e vamos incluir e posicionar as duas etiquetas na tela logo no início do jogo. Para isso, abra o arquivo “HelloWorldScene.cpp” e adicione as seguintes linhas de código:

HelloWorld::pontos = 0;

HelloWorld::chances = 0;

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

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

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

addChild(HelloWorld::etiquetaDePontos);

HelloWorld::etiquetaDeChances = CCLabelTTF::create(“Chances: 0”,“”,40);

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

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

addChild(HelloWorld::etiquetaDeChances);

logo abaixo dessas linhas:

for(int i=0;i<18;i++) {

    CCSprite* bloco = CCSprite::createWithSpriteFrameName(“bloco.png”);

    bloco->setScale((0.1*size.height)/bloco->boundingBox().size.height);

    bloco->setPosition(ccp(size.width/2 + (i%6 – 2.5)*bloco->boundingBox().size.width,0.8*size.height – (i/6)*bloco->boundingBox().size.height));

    HelloWorld::blocos->addObject(bloco);

    addChild(bloco);

}

Note que iniciamos as variáveis “pontos” e “chances” com o valor 0, obviamente. Logo após, escrevemos nas duas etiquetas no início do jogo, as posicionamos na tela, as deixamos com a cor preta e as incluímos na tela com o método “addChild”. Ainda faltam algumas coisas: modificar os valores das variáveis e o texto das etiquetas na hora certa. Vamos iniciar com a modificação do texto da etiqueta de chances. Adicione as seguintes linhas de código:

char str[15];

HelloWorld::chances++;

sprintf(str,“Chances: %i”,HelloWorld::chances);

HelloWorld::etiquetaDeChances->setString(str);

logo abaixo dessas:

if(HelloWorld::bola->getPositionY()-HelloWorld::bola->boundingBox().size.height/2<=0&&HelloWorld::vetorDirecao[1]<0) {

    HelloWorld::bola->setPosition(ccp(size.width/2,0.25*size.height));

    HelloWorld::vetorDirecao[0] = sqrt(2)/2;

    HelloWorld::vetorDirecao[1] = sqrt(2)/2;

Note que as linhas foram adicionadas dentro da estrutura de seleção “se” responsável por identificar o momento que a bola de fogo sai da tela. Nesse momento, nós também adicionamos uma unidade no valor da variável “chances” e modificamos o texto da etiqueta “etiquetaDeChances” para mostrar o valor atualizado de vezes que o jogador deixou a bola de fogo sair da tela. Isso é o suficiente para que o jogo mostre na tela sempre a quantidade de vezes que a bola de fogo saiu.

Para finalizar, vamos modificar o texto da etiqueta de pontos quando o jogador quebra um bloco amarelo. Adicione as seguintes linhas de código:

char str[15];

HelloWorld::pontos++;

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

HelloWorld::etiquetaDePontos->setString(str);

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

if(HelloWorld::blocos->count()==0) {

    unscheduleAllSelectors();

    CCLabelTTF* endGame = CCLabelTTF::create(“Estagio completo”,“”,50);

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

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

    addChild(endGame);

}

logo abaixo dessas:

else {

    HelloWorld::vetorDirecao[1] = -HelloWorld::vetorDirecao[1];

    removeChild(blocoEscolhido);

    HelloWorld::blocos->removeObject(blocoEscolhido,true);

}

Verifique onde adicionamos esse código. Perceba que ele foi adicionado na estrutura de seleção responsável por verificar se um bloco foi destruído. Caso um bloco amarelo seja destruído, nós incrementamos a variável “pontos” e modificamos a etiqueta “etiquetaDePontos” para mostrar o valor atualizado de blocos já quebrados pelo jogador. Para deixar o jogo mais profissional, adicionamos uma estrutura de seleção que verifica se todos os blocos foram destruídos. Caso isso aconteça, o jogo é parado e é mostrada na tela uma etiqueta que indica que o estágio foi completado. Finalmente colocamos todas as HUDs necessárias para finalizar o desenvolvimento desse jogo. A Figura 1 mostra como fica o jogo no final, quando todos os blocos são destruídos. Para os curiosos de plantão, segue um vídeo logo abaixo da Figura 1 que mostra o gameplay desse jogo. Vale lembrar que ele está espelhado porque eu não fiz qualquer edição no vídeo.

Figura 1 - Final do jogo

Figura 1 – Final do jogo

Finalizamos o desenvolvimento de mais um game com esse tutorial. Vimos como adicionar elementos de HUD para mostrar o desempenho do jogador e para indicar o final do jogo. Vimos que precisávamos incluir duas variáveis que armazenavam a quantidade de blocos destruídos e a quantidade de vezes que a bola de fogo saiu da tela. No próximo tutorial iniciaremos o desenvolvimento de outro game, creio eu que faremos um jogo ao estilo do famoso e viciante Angry Birds (créditos a Rovio).

Um grande abraço e nos vemos no próximo tutorial. []




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