Tutorial: Utilizando o motor físico Box2D em conjunto com o Cocos2d-x – Parte 6

A animação que fizemos no tutorial passado com simulação física ficou muito legal, não acharam? Mas tem como melhorar.

Vamos adicionar as texturas nos objetos e ver como fica.

No tutorial passado eu mostrei a vocês um novo tipo de junta, a de distância. Incrementamos o nosso sistema articulado incluindo um pêndulo na ponta e o ligamos por meio de uma junta de distância. Isso fez com que o motor colocasse o pêndulo em movimentação. Nesse tutorial eu não vou apresentar conceitos novos a vocês. Não vou mostrar outra junta do Box2D e nem vamos deixar o nosso sistema articulado mais complexo. Nesse tutorial nós vamos adicionar texturas no modelo, deixando – o mais parecido com o mundo real e não mostrando apenas vários retângulos, ou outras primitivas geométricas. Bora adicionar figurinhas em nosso sistema articulado? ;D

Tirando o Debug Draw

Primeiramente vamos fazer com que o Cocos2d-x não mostre mais na tela as primitivas do Box2D. Na verdade, o Box2D está ali apenas para realizar os cálculos físicos necessários para desempenhar a simulação e não para mostrar os modelos físicos na tela. O que faremos então? Vamos eliminar todas primitivas geométricas que estão sendo desenhadas pelo debug draw e adicionaremos no lugar delas algumas figuras que lembram objetos do mundo real. Resumindo, adicionaremos texturas exatamente onde estão os corpos rígidos do Box2D.

Para não mostrar o debug draw, vamos mudar o código do tutorial passado (caso você não o fez, por favor clique aqui). Abra o arquivo “HelloWorldScene.h” e apague essa linha de código:

B2DebugDrawLayer* debugDrawLayer;

e essa:

virtual void draw();

Agora abra o arquivo “HelloWorldScene.cpp” e remova essas linhas:

HelloWorld::debugDrawLayer = B2DebugDrawLayer::create(HelloWorld::world,PTM_RATIO);

addChild(HelloWorld::debugDrawLayer,9999);

e essas:

void HelloWorld::draw() {

    CCLayer::draw();

    ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position);

    kmGLPushMatrix();

    HelloWorld::world->DrawDebugData();

    kmGLPopMatrix();

}

Se você for compilar e ver o resultado, não será mostrado nada na tela do aparelho, porque removemos o debug draw. Aqueles arquivos que incluímos quando fizemos esse tutorial (“B2DebugDrawLayer.h”, “B2DebugDrawLayer.cpp”, “GLES-Render.h” e “GLES-Render.cpp”), agora, para esse momento, são desnecessários. Apesar de não ser mostrado algo na tela, o Box2D está realizando os cálculos de física e os objetos rígidos ainda existem.

Vamos adicionar as texturas.

 

Adicionando as texturas

Agora vamos incluir as texturas nos objetos rígidos criados no Box2D. Para isso, abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:

b2Body* corpoPolia;

b2Body* corpoEixo1;

b2Body* corpoEixo2;

b2Body* corpoPendulo;

cocos2d::CCSprite* texturaPolia;

cocos2d::CCSprite* texturaEixo1;

cocos2d::CCSprite* texturaEixo2;

cocos2d::CCSprite* texturaPendulo;

logo abaixo dessa linha (lembre-se de remover as linhas que eu falei antes):

b2World* world;

Nesse arquivo já fizemos o necessário. Agora abra o arquivo “HelloWorldScene.cpp” e modifique as linhas de código como eu vou explicar. Nessa linha:

b2Body* corpoPolia = HelloWorld::world->CreateBody(&definicaoCorpoPolia);

mude para essa:

HelloWorld::corpoPolia = HelloWorld::world->CreateBody(&definicaoCorpoPolia);

Nessa linha:

b2Body* corpoEixo1 = HelloWorld::world->CreateBody(&definicaoEixo1);

mude para essa:

HelloWorld::corpoEixo1 = HelloWorld::world->CreateBody(&definicaoEixo1);

Nessa linha:

b2Body* corpoEixo2 = HelloWorld::world->CreateBody(&definicaoEixo2);

mude para essa:

HelloWorld::corpoEixo2 = HelloWorld::world->CreateBody(&definicaoEixo2);

Nessa linha:

b2Body* corpoPendulo = HelloWorld::world->CreateBody(&definicaoCorpoPendulo);

mude para essa:

HelloWorld::corpoPendulo = HelloWorld::world->CreateBody(&definicaoCorpoPendulo);

O que fizemos aqui? Antes, nós criamos alguns corpos rígidos e os adicionamos no mundo do Box2D. Porém, alguns desses corpos, a partir de agora, serão utilizados para adquirir informações de localização e angulação. Isso é importante para que as texturas sejam posicionadas e anguladas da forma correta, assim como acontece no mundo do Box2D. Para que essas informações estejam disponíveis, eu criei os corpos em variáveis que fazem parte da classe “HelloWorld”. Vocês podem ver essas mesmas variáveis listadas no código que adicionamos no arquivo “HelloWorldScene.h”.

Agora vamos incluir as texturas no Cocos2d-x por meio de Sprites. Para que possamos adicionar Sprites no ambiente, precisamos incluir o sprite sheet no projeto do aplicativo. Caso você não lembre de nada disso do que eu estou falando, abra esse tutorial e tire as suas dúvidas. Eu mesmo criei o sprite sheet, e os arquivos dele vocês podem baixar aqui: Texturas. Descompacte o arquivo dentro da pasta “Resources”. Agora vamos criar esses Sprites no código. Abra o arquivo “HelloWorldScene.cpp” e adicione as seguintes linhas de código:

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

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

texturaMotor->setPosition(ccp(corpoCaixaMotor->GetPosition().x*PTM_RATIO,corpoCaixaMotor->GetPosition().y*PTM_RATIO));

addChild(texturaMotor);

HelloWorld::texturaPolia = CCSprite::createWithSpriteFrameName(“Polia.png”);

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

addChild(HelloWorld::texturaPolia);

HelloWorld::texturaEixo1 = CCSprite::createWithSpriteFrameName(“Viga.png”);

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

HelloWorld::texturaEixo1->setScale(0.67);

addChild(HelloWorld::texturaEixo1);

HelloWorld::texturaEixo2 = CCSprite::createWithSpriteFrameName(“Viga.png”);

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

addChild(HelloWorld::texturaEixo2);

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

texturaSustentador->setPosition(ccp(corpoSustentador->GetPosition().x*PTM_RATIO,3*PTM_RATIO));

addChild(texturaSustentador);

HelloWorld::texturaPendulo = CCSprite::createWithSpriteFrameName(“Pendulo.png”);

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

addChild(HelloWorld::texturaPendulo);

logo abaixo dessa linha:

HelloWorld::world->CreateJoint(&definicaoJuntaEixoPendulo);

Acabamos de adicionar os Sprites correspondentes a cada objeto rígido que criamos antes: o motor, a polia, o eixo 1, o eixo 2, o sustentador e o pêndulo. Se você compilar e executar esse código, verá que apenas são inclusas as texturas no ambiente e elas não se movimentam como no nosso último tutorial. Para isso, precisamos atualizar os Sprites com as informações de posição e angulação de cada objeto rígido que sofre movimentação. Resumindo, precisamos modificar a função “atualiza”, que é chamada continuamente, para reposicionar e angular os Sprites. No mesmo arquivo, adicione essas linhas de código:

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

HelloWorld::texturaPolia->setRotation(-180*HelloWorld::corpoPolia->GetAngle()/3.141592);

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

HelloWorld::texturaEixo1->setRotation(-180*HelloWorld::corpoEixo1->GetAngle()/3.141592);

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

HelloWorld::texturaEixo2->setRotation(-180*HelloWorld::corpoEixo2->GetAngle()/3.141592);

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

logo abaixo dessa:

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

Agora sim o serviço está completo. Compile o seu código, o execute e veja que coisa linda. Exageros a parte, mas ficou bem mais legal do que antes. *_*

Para os curiosos de plantão, o vídeo abaixo mostra o aplicativo executando com as texturas e não mais com objetos geométricos. Como o vídeo não ficou lá aquelas coisas, segue um print da tela do meu aparelho na Figura 1.

Figura 1 - Sistema articulado

Figura 1 – Sistema articulado

 

Nesse tutorial eu mostrei a vocês como utilizar o Box2D em conjunto com o Cocos2d-x. Vimos que existem praticamente dois mundos distintos: o do Cocos2d-x, que é mais visual e é apresentado para o jogador, e o do Box2D, que é o que faz as simulações físicas. Vimos que o mundo do Box2D não precisa ser mostrado na tela do celular e que ele serve apenas para fazer as simulações físicas. Para que o mundo fique parecido com o mundo real, incluímos Sprites no mundo do Cocos2d-x, que seguem a posição e a angulação dos objetos rígidos simulados no Box2D. Dessa forma, os Sprites fazem exatamente a mesma movimentação dos objetos rígidos do Box2D.

No próximo tutorial eu vou quebrar um pouco essa sequência de tutoriais sobre Box2D e falarei sobre como incluir efeitos sonoros pelo Cocos2d-x. Veja que existe diferença entre o próximo tutorial e esse tutorial, que incluímos efeitos sonoros no código Java e não diretamente no Cocos2d-x.

Por hoje é isso pessoal. Nos vemos no próximo tutorial. []s

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