Desenvolvendo um Jogo Digital do Zero: Parte 10 – Iniciando a Programação

Boa tarde pessoal.

Agora eu, Santiago, escreverei os próximos artigos sobre o desenvolvimento de um jogo do zero. Lembrando que já passamos por quatro artigos sobre Game Design escritos pelo Fabiano e cinco artigos sobre a arte do jogo escritos pelo Filipe.

Assumirei agora a parte de programação do jogo.

Partiu.

Todas as partes da saga:

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

Antes de tudo, farei uma referência ao Game Design Document, para sabermos tudo sobre como o jogo deve ser programado. De início, precisaremos apenas das informações referentes à tela de gameplay. A Figura 1 mostra um esboço dessa tela feito pelo designer.

 

Análise dos elementos gráficos

Fazendo uma breve análise da Figura 1, podemos selecionar elementos gráficos que sofrerão algum tipo de interação ou terão vida própria. Esses elementos precisam ser tratados de forma isolada, para que ocorra o dinamismo durante o jogo. Então, eu separei os elementos gráficos da tela de gameplay da seguinte maneira:

  • Surfista do jogador: movimenta para cima a para baixo, conforme a preferência do jogador;
  • Surfista do NPC: movimenta para cima e para baixo, conforme as decisões tomadas por um algoritmo de IA (veremos em um futuro artigo);
  • Tubarão: elemento gráfico que representará a bola do pong. Se movimentará como tal;
  • Polvo: elemento gráfico que aparecerá de tempos em tempos na superfície da água. Ele representa um “power up” do jogo;
  • Botões: os elementos gráficos de interação do jogador com o game.

Figura 1 - Tela de gameplay esboçada pelo designer

Figura 1 – Tela de gameplay esboçada pelo designer

Além dos elementos que possuem movimentação, animação ou interação, existem aqueles elementos gráficos que apenas estão no jogo para deixá-lo mais atrativo. Esses são:

  • O mar: elemento gráfico que contextualiza o cenário onde acontece o jogo;
  • As ondas: outro elemento gráfico que contextualiza o cenário.

Poderíamos pensar, também, em algo como as ondas se movimentando para a esquerda e para a direita repetidamente. Isso transformaria o elemento “ondas” em um elemento que possui movimentação. Porém, como nada foi especificado no Game Design Document a respeito disso, não faremos com que as ondas se movimentem. Até porque isso limita o escopo do artigo.

Dessa forma, os dois elementos foram agrupados em um único elemento denominado “O mar”, que se resume a uma foto que servirá de fundo para o nosso game. Com essas informações, podemos criar o nosso sprite sheet. Esse artigo não explicará de forma clara o que é um sprite sheet, se você quiser saber melhor, abra esse tutorial.

 

Criação do sprite sheet

Após uma análise rápida sobre a tela de gameplay, elegemos um total de sete elementos gráficos que precisam ser tratados de forma independente: dois surfistas, dois botões de interação, o tubarão, o polvo e o fundo. Dessa forma, nosso sprite sheet terá esses itens separadamente para que a execução do game ocorra conforme o projetado no Game Design Document.

Alguns leitores mais experientes e atenciosos, podem se perguntar nesse momento como ficam as animações existentes no game. É normal que existam mais frames no sprite sheet de um mesmo elemento gráfico, para que seja possível animá-lo durante o jogo. Por enquanto, nos preocuparemos apenas em mostrar a tela inicial de gameplay. Assim, o jogo não terá nenhuma animação no início. Trabalhando dessa forma, nós deixamos o artigo mais simples e o processo de programação mais modularizado.

Figura 2 - Sprite sheet do jogo

Figura 2 – Sprite sheet do jogo

O sprite sheet foi criado como mostra a Figura 2. Nela estão especificados os sprite frames existentes e quais são os seus nomes para que eles possam ser devidamente referenciados no código. Você pode baixar os arquivos de sprite sheet aqui.

 

Criando o projeto no Cocos2d-x

Note que esse artigo não indicará como se cria um projeto no Cocos2d-x e muito menos explica o que ele é. Você pode saber mais sobre como criar um projeto no Cocos2d-x e sobre o que se trata, nesses dois tutoriais (versão antiga e nova versão).

Crie dois projetos: um projeto com nome de pacote “com.FabricaDeJogos.SharkPong” e um com nome de projeto “SharkPong”. Selecione uma plataforma Android que melhor lhe convier. Eu escolhi desenvolver para Android 2.3.4. A Figura 3 demonstra a criação do projeto com o Cocos2d-x versão 2.1.4.

Figura 3 - Criando o projeto

Figura 3 – Criando o projeto

Após criar o projeto, vamos fazer uma limpeza nele. Entre na pasta “Resources” e apague a imagem “HelloWorld.png”. Agora copie para dentro dessa mesma pasta o conteúdo do arquivo compactado que contém os arquivos de sprite sheet criados nesse artigo. Será por meio desses arquivos que poderemos criar os Sprites do nosso game.

Feito isso, vamos à edição do código. Abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:

cocos2d::CCSprite* paJogador;

cocos2d::CCSprite* paIA;

cocos2d::CCSprite* tubarao;

cocos2d::CCSprite* polvo;

cocos2d::CCSprite* botaoDescer;

cocos2d::CCSprite* botaoSubir;

Logo abaixo dessa:

static cocos2d::CCScene* scene();

Criamos um Sprite para cada elemento gráfico destacado anteriormente, com exceção do fundo, que não precisa de qualquer modificação durante a execução do jogo. Agora vamos à lógica.

Salve o arquivo “HelloWorldScene.h” e abra o arquivo “HelloWorldScene.cpp”. Modifique a seguinte linha de código:

pCloseItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width – 20, 20) );

de forma que ela fique assim:

pCloseItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width – 20, CCDirector::sharedDirector()->getWinSize().height – 20) );

Acabamos de reposicionar o botão que fecha o aplicativo. Isso foi necessário porque posicionaremos um botão de interação com o jogo exatamente no mesmo lugar onde ele ficava. Agora ele ficará na parte superior direita da tela.

Remova o bloco de código que vem por padrão no aplicativo Cocos2d-x, pois não precisaremos mais dele. Esse código SE inicia nessas linhas (inclusive):

/////////////////////////////

// 3. add your codes below…

// add a label shows “Hello World”

// create and initialize a label

CCLabelTTF* pLabel = CCLabelTTF::create(“Hello World”, “Thonburi”, 34);

e termina nessa (inclusive):

this->addChild(pSprite, 0);

Agora, para finalizar, adicione as seguintes linhas de código exatamente onde você apagou as últimas.

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

CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(“spriteSheet.plist”);

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

if(size.width/size.height>fundo->boundingBox().size.width/fundo->boundingBox().size.height)

    fundo->setScale(size.width/fundo->boundingBox().size.width);

else

    fundo->setScale(size.height/fundo->boundingBox().size.height);

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

addChild(fundo);

HelloWorld::paJogador = CCSprite::createWithSpriteFrameName(“SurfistaJogador1.png”);

HelloWorld::paJogador->setScale((0.2*size.height)/HelloWorld::paJogador->boundingBox().size.height);

HelloWorld::paJogador->setPosition(ccp(0.1*size.width,0.9*size.height));

addChild(HelloWorld::paJogador);

HelloWorld::paIA = CCSprite::createWithSpriteFrameName(“SurfistaIA1.png”);

HelloWorld::paIA->setScale((0.2*size.height)/HelloWorld::paIA->boundingBox().size.height);

HelloWorld::paIA->setPosition(ccp(0.9*size.width,0.3*size.height));

HelloWorld::paIA->setFlipY(true);

addChild(HelloWorld::paIA);

HelloWorld::tubarao = CCSprite::createWithSpriteFrameName(“Tubarao1.png”);

HelloWorld::tubarao->setScale((0.2*size.height)/HelloWorld::tubarao->boundingBox().size.height);

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

addChild(HelloWorld::tubarao);

HelloWorld::polvo = CCSprite::createWithSpriteFrameName(“Polvo1.png”);

HelloWorld::polvo->setScale((0.1*size.height)/HelloWorld::polvo->boundingBox().size.height);

HelloWorld::polvo->setPosition(ccp(0.8*size.width,0.8*size.height));

addChild(HelloWorld::polvo);

HelloWorld::botaoDescer = CCSprite::createWithSpriteFrameName(“BotaoDescer.png”);

HelloWorld::botaoDescer->setScale((0.2*size.height)/HelloWorld::botaoDescer->boundingBox().size.height);

HelloWorld::botaoDescer->setPosition(ccp(

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

addChild(HelloWorld::botaoDescer);

HelloWorld::botaoSubir = CCSprite::createWithSpriteFrameName(“BotaoSubir.png”);

HelloWorld::botaoSubir->setScale((0.2*size.height)/HelloWorld::botaoSubir->boundingBox().size.height);

HelloWorld::botaoSubir->setPosition(ccp(

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

addChild(HelloWorld::botaoSubir);

Se você analisar o código, perceberá que apenas abrimos cada elemento gráfico identificado por meio de um Sprite, escalamo-nos para que eles fiquem de acordo com o tamanho mostrado no esboço e os posicionamos cada um em seus respectivos lugares. Se você compilar e executar o programa, perceberá que será mostrado na tela algo muito parecido com o que foi esboçado pelo designer, o que demonstra sucesso nesse início de programação. Será mostrado algo parecido com a Figura 4.

Figura 4 - Execução do jogo

Figura 4 – Execução do jogo

Vimos nesse artigo que precisamos primeiramente identificar quais são os elementos gráficos que sofrem modificações no decorrer do game. Para cada elemento gráfico, precisamos especificar os seus sprite frames para que seja possível incluí-los de forma separada no jogo. Cada elemento foi representado no código por um Sprite, que por sua vez, abria os sprite frames especificados nos arquivos de sprite sheet.

Veremos no próximo artigo como adicionar a interação com o surfista por meio dos botões em forma de concha.

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