Tutorial: Desenvolvendo um jogo de guiar bolinha em labirinto – Parte 4: Adicionando Sprites

É muito legal ver quando nosso jogo começa a criar corpo.

Mas ainda falta deixá-lo parecido com os objetos existentes no mundo real.

Hoje, colocaremos imagens nos objetos rígidos, deixando o nosso jogo como um labirinto feito de madeira.

Go go go …

No tutorial passado nós incluímos as paredes no nosso jogo de guiar a bolinha no labirinto. Estamos nos aproximando do fim desse game, estão percebendo? Nesse tutorial eu adicionarei as “figurinhas” sobre os objetos rígidos no Box2D, fazendo com que o cenário feito de caixas tenha o aspecto de um labirinto feito de madeira. Além disso, colocaremos um Sprite de bola de aço que acompanha o objeto rígido pertencente à bola.

Dando início ao tutorial, baixe esse arquivo: Texturas para o game. Depois, descompacte-o na pasta “Resources”, existente no projeto criado no Cocos2d-x. Eu criei um sprite sheet que contém arquivos de imagens para o fundo do labirinto, para as paredes e para a bolinha de aço. Caso você não saiba para que servem os arquivos de sprite sheet contidos no arquivo compactado ou não lembre como criá-los, dê uma olhada nesse tutorial. Após a descompactação na pasta correta, você já pode usar o sprite sheet para criar os Sprites que servirão como texturas para os objetos rígidos existentes no mundo do Box2D.

Agora vamos incluir o código responsável por adicionar os Sprites no mundo do Cocos2d-x. Como de praxe, modificaremos a versão do código obtida após o término do último tutorial. Caso você não o fez, clique aqui e o faça para que possamos dar continuidade nesse tutorial. Primeiramente abra o arquivo “HelloWorldScene.h” e adicione a seguinte linha de código:

cocos2d::CCSprite* bolinhaSprite;

logo abaixo desse linha, essa adicionada no último tutorial:

b2Body* bolinha;

Agora abra o arquivo “HelloWorldScene.cpp” e adicione o seguinte código:

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

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

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

addChild(fundoSprite);

CCSprite* caixasSprite[6];

caixasSprite[0] = CCSprite::createWithSpriteFrameName(“Parede.png”);

caixasSprite[0]->setScaleX(288.0/caixasSprite[0]->boundingBox().size.width);

caixasSprite[0]->setScaleY(32.0/caixasSprite[0]->boundingBox().size.height);

caixasSprite[0]->setPosition(ccp(caixas[0]->GetPosition().x*PTM_RATIO,caixas[0]->GetPosition().y*PTM_RATIO));

addChild(caixasSprite[0]);

caixasSprite[1] = CCSprite::createWithSpriteFrameName(“Parede.png”);

caixasSprite[1]->setScaleX(288.0/caixasSprite[1]->boundingBox().size.width);

caixasSprite[1]->setScaleY(32.0/caixasSprite[1]->boundingBox().size.height);

caixasSprite[1]->setPosition(ccp(caixas[1]->GetPosition().x*PTM_RATIO,caixas[1]->GetPosition().y*PTM_RATIO));

addChild(caixasSprite[1]);

caixasSprite[2] = CCSprite::createWithSpriteFrameName(“Parede.png”);

caixasSprite[2]->setScaleX(128.0/caixasSprite[2]->boundingBox().size.width);

caixasSprite[2]->setScaleY(32.0/caixasSprite[2]->boundingBox().size.height);

caixasSprite[2]->setRotation(90);

caixasSprite[2]->setPosition(ccp(caixas[2]->GetPosition().x*PTM_RATIO,caixas[2]->GetPosition().y*PTM_RATIO));

addChild(caixasSprite[2]);

caixasSprite[3] = CCSprite::createWithSpriteFrameName(“Parede.png”);

caixasSprite[3]->setScaleX(64.0/caixasSprite[3]->boundingBox().size.width);

caixasSprite[3]->setScaleY(32.0/caixasSprite[3]->boundingBox().size.height);

caixasSprite[3]->setRotation(90);

caixasSprite[3]->setPosition(ccp(caixas[3]->GetPosition().x*PTM_RATIO,caixas[3]->GetPosition().y*PTM_RATIO));

addChild(caixasSprite[3]);

caixasSprite[4] = CCSprite::createWithSpriteFrameName(“Parede.png”);

caixasSprite[4]->setScaleX(64.0/caixasSprite[4]->boundingBox().size.width);

caixasSprite[4]->setScaleY(32.0/caixasSprite[4]->boundingBox().size.height);

caixasSprite[4]->setRotation(90);

caixasSprite[4]->setPosition(ccp(caixas[4]->GetPosition().x*PTM_RATIO,caixas[4]->GetPosition().y*PTM_RATIO));

addChild(caixasSprite[4]);

caixasSprite[5] = CCSprite::createWithSpriteFrameName(“Parede.png”);

caixasSprite[5]->setScaleX(64.0/caixasSprite[5]->boundingBox().size.width);

caixasSprite[5]->setScaleY(32.0/caixasSprite[5]->boundingBox().size.height);

caixasSprite[5]->setRotation(90);

caixasSprite[5]->setPosition(ccp(caixas[5]->GetPosition().x*PTM_RATIO,caixas[5]->GetPosition().y*PTM_RATIO));

addChild(caixasSprite[5]);

HelloWorld::bolinhaSprite = CCSprite::createWithSpriteFrameName(“Bolinha.png”);

HelloWorld::bolinhaSprite->setPosition(ccp(HelloWorld::bolinha->GetPosition().x*PTM_RATIO,HelloWorld::bolinha->GetPosition().y*PTM_RATIO));

addChild(HelloWorld::bolinhaSprite);

logo abaixo dessa linha, também adicionada no tutorial anterior:

caixas[5]->CreateFixture(&cascaCaixas5);

O que fizemos acima? Antes de tudo, eu abri o sprite sheet para que pudéssemos criar e incluir Sprites no mundo do Cocos2d-x. Logo após, eu criei, posicionei e adicionei um Sprite que representa o fundo do labirinto no mundo do Cocos2d-x. Continuando, eu criei e escalei (mudei o tamanho) dos Sprites que representam duas paredes na horizontal e os adicionei ao jogo. Para terminar de criar as paredes, adicionei mais quatro delas na vertical, o que necessitou que eu rotacionasse os Sprites em 90 graus, para deixá-los em pé. Finalizando, eu incluí um Sprite que representa a bolinha de aço.

Notem que eu apenas adicionei esse Sprite no ambiente, mas não o fiz seguir o objeto rígido que representa a bolinha de aço. Para que o Sprite acompanhe corretamente esse objeto rígido, é necessário que, a cada atualização do mundo do Box2D, você atualize também a nova posição do Sprite. Isso fará com que a cada movimentação que aconteça no objeto rígido que representa a bolinha de aço, a posição do Sprite seja atualizada, fazendo com que ele se movimente também. Para isso, adicione a seguinte linha de código:

HelloWorld::bolinhaSprite->setPosition(ccp(HelloWorld::bolinha->GetPosition().x*PTM_RATIO,HelloWorld::bolinha->GetPosition().y*PTM_RATIO));

logo abaixo dessa:

HelloWorld::mundo->Step(dt,3,2);

Compile o código e execute o jogo. Perceba que, agora, todos os objetos rígidos do jogo tem um Sprite que os representam no mundo do Cocos2d-x. Isso fez com que cada parede tenha a sua respectiva imagem de madeira, o fundo tenha uma imagem de uma madeira ou pouco mais clara e a bolinha tenha uma imagem de uma bolinha de aço. Note que, mesmo após adicionarmos os Sprites, o debug draw continua sendo mostrado na tela. Se você quiser ver como fica o resultado sem ele, comente essa linha de código (adicione duas barras “//” no começo da linha):

addChild(HelloWorld::debugDrawLayer,9999);

Isso fará com que o jogo seja executado sem o debug draw, ou seja, como ele realmente deve aparecer na tela do aparelho. Se você não lembra muito bem sobre o que é e para que serve o debug draw, veja esse tutorial. A Figura 1 mostra o jogo sendo executado sem o debug draw.

Figura 1 - Jogo executando sem o debug draw

Figura 1 – Jogo executando sem o debug draw

 

Nesse tutorial nós vimos como adicionar Sprites que representam cada objeto rígido existente no mundo do Box2D. Vimos que, para que o Sprite da bolinha de aço ande conforme o objeto rígido que a representa no mundo do Box2D, é necessário atualizar a posição do Sprite a cada mudança no mundo do Box2D. Ao final nós retiramos temporariamente o debug draw para que pudéssemos visualizar como estava o jogo. Não esqueça de “descomentar” a linha de código que comentamos por último. O debug draw ainda será importante nos próximos tutoriais.

No próximo tutorial nós adicionaremos as bocas que a bolinha não poderá entrar e a boca que a bolinha deverá ser colocada. Para isso, precisaremos programar as bocas, as suas funcionalidades e adicionar um Sprite que representa cada uma delas no mundo do Cocos2d-x. Mas isso não é tema desse tutorial.

Um grande abraço e nos vemos adiante. []

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