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

Muitos dos jogos que vocês conhecem tem uma simulação física muito parecida com o que acontece no mundo real.

Que tal passarmos esses tipos de simulação para os celulares? Bora lá?

No último tutorial eu apresentei a vocês como utilizar as informações vindas do acelerômetro de um aparelho Android. Nesse tutorial veremos como podemos fazer simulações físicas em nossos jogos sem precisarmos saber conceitos de física a fundo. Para isso, eu mostrarei uma biblioteca física que já vem com a biblioteca Cocos2d-x, e alguns conceitos básicos. Vamos programar nossa primeira simulação física?

 

O motor físico Box2D

O Box2D é um motor de simulação física de corpos rígidos no plano (2D). Ele possui código aberto, ou seja, você pode usá-lo e modificá-lo conforme a sua vontade, e já está incluso no motor Cocos2d-x. O mais legal é que você não precisa sequer baixar a biblioteca para programar a simulação física, ela já vem junto com o Cocos2d-x. Quando você compila o seu programa em Cocos2d-x a primeira vez, note que o Box2D também é compilado junto, mesmo se você não usa o motor físico. A Figura 1 mostra o momento que a biblioteca do Box2D começa a ser compilada.

Figura 1 - Compilação da biblioteca do Box2D

Figura 1 – Compilação da biblioteca do Box2D

Por ser uma biblioteca que busca simular a física de colisão de corpos rígidos do mundo real, qualquer unidade de medida utilizada deverá ser em metros. Então, quando você diz que um corpo é quadrado com a unidade de medida 1, você está querendo dizer que é um quadrado com 1 metro de lado. Isso é um pouco confuso no início, visto que as pessoas normalmente lidam em jogos com a unidade pixels e não metros.

Você verá que esse problema, na verdade, nem é tão complicado assim de resolver. Os próprios criadores e mantenedores da biblioteca realizam os cálculos físicos baseados em um valor de conversão. Como assim, Santy? Quando você cria um mundo físico, você passa um valor real que determina a razão Pixels por Metro. A partir daí, basta usar essa razão quando você precisar converter do mundo físico para a tela do aparelho.

O básico é isso, agora vamos para a parte interessante.

 

Objetos Rígidos no Box2D

A parte interessante de se utilizar um motor físico no desenvolvimento de jogos, é que vocês não precisam serem experts em física para poderem simular algo legal. Veremos no decorrer desses tutoriais que vocês farão simulações lindas, daquelas que vocês olham em jogos e pensam: “Meu, esse jogo é muito real”.

Quem precisa saber bastante de física são os desenvolvedores do motor físico e não você. Mas ainda assim, precisamos conhecer alguns conceitos básicos para podermos brincar com o motor.

  • Corpos (b2Body): são os objetos rígidos em si. Quando você quer criar um objeto que precisa ter tratamento de colisão, atrito ou coisa do tipo, você precisa criar um corpo. Um corpo possui várias informações que precisam ser definidas pelo programador para que ele possa ser simulado corretamente. Entre essas informações estão a definição dele, o formato e como se comporta e qual é o material dele.
  • Definição de Corpos (b2BodyDef): descreve basicamente como um corpo se comportará no mundo físico. Ele se move ou é um objeto parado (chão, por exemplo)? Onde ele está localizado no mundo e qual é a angulação dele?
  • Formatos (b2Shape): descreve a geometria do corpo. Pode ser um polígono, uma linha, um conjunto de linhas interligadas como se fossem uma corrente, pode ser um círculo, um quadrado, um retângulo e por aí vai.
  • Material (b2FixtureDef): descreve como é o material do corpo. Ele pode ser bem áspero ou mais liso (desliza mais), pode ser bastante elástico (quica mais quando colide) ou mais duro e pode ser mais pesado (densidade alta) ou mais leve.

 

Criando uma aplicação simples com simulação física

Para utilizarmos esses conceitos e criarmos nossa primeira simulação física, primeiramente criem um novo projeto no Cocos2d-x. Se vocês não lembram como, façam esse tutorial. O mundo físico, normalmente não é mostrado na tela, apenas as “figurinhas” que são “coladas” sobre os corpos rígidos.

Para que possamos visualizar os corpos rígidos, é necessário realizar um debug draw. Um debug draw é o processo que é feito unicamente para mostrar o mundo físico na tela com o principal intuito de correção de erros de programação. Nesse nosso caso, não estamos corrigindo erros de programação, mas vamos fazer o debug draw para podermos ver a simulação física em si.

Para isso, baixe todos os arquivos com extensões “.cpp” e “.h” desse site e copie-os na pasta “Classes” do seu projeto Cocos2d-x. O debug draw é um processo meio chato de fazer e eu estou pegando pronto. Ainda bem que existem pessoas legais que disponibilizam códigos para testarmos. =]

Esses arquivos precisam ser compilados junto com o seu programa, até porque eles fazem parte dele. Mas somente movê-los para a pasta “Classes” não é suficiente para eles serem compilados no Cygwin. Você precisa apontar esses arquivos como pertencentes ao seu projeto. Para isso, abra no Eclipse o arquivo “Android.mk”, localizado na pasta “proj.android/jni”. Nessa parte do arquivo:

LOCAL_SRC_FILES := hellocpp/main.cpp

../../Classes/AppDelegate.cpp

../../Classes/HelloWorldScene.cpp

mude para:

LOCAL_SRC_FILES := hellocpp/main.cpp

../../Classes/AppDelegate.cpp

../../Classes/HelloWorldScene.cpp

../../Classes/GLES-Render.cpp

../../Classes/B2DebugDrawLayer.cpp

Pronto. Agora os arquivos que você baixou serão compilados junto com os seus arquivos do jogo. Vamos acionar o debug draw no código e incluir um corpo rígido em um mundo físico. Abra o arquivo “HelloWorldScene.h”. Nessa parte:

#define __HELLOWORLD_SCENE_H__

Adicione logo abaixo as seguintes linhas de código:

#include “Box2D/Box2D.h”

#include “B2DebugDrawLayer.h”

#define PTM_RATIO 40

Ainda no mesmo arquivo, nessa parte:

CREATE_FUNC(HelloWorld);

Adicione abaixo as seguintes linhas de código:

void atualiza(float dt);

B2DebugDrawLayer* debugDrawLayer;

b2World* world;

virtual void draw();

Agora abra o aquivo “HelloWorldScene.cpp”. Nessa parte do código:

// add “HelloWorld” splash screen”

apague tudo até (inclusive) aqui:

this->addChild(pSprite, 0);

Nesse mesmo lugar, adicione o seguinte código:

b2Vec2 gravidade = b2Vec2(0.0f,-9.78f);

HelloWorld::world = new b2World(gravidade);

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

addChild(HelloWorld::debugDrawLayer,9999);

b2BodyDef definicaoCorpo;

definicaoCorpo.type = b2_dynamicBody;

definicaoCorpo.position.Set((size.width/2)/PTM_RATIO,(size.height/2)/PTM_RATIO);

b2Body* corpo = HelloWorld::world->CreateBody(&definicaoCorpo);

b2CircleShape circulo;

circulo.m_radius = 1;

b2FixtureDef casca;

casca.shape = &circulo;

casca.density = 1.0f;

corpo->CreateFixture(&casca);

schedule(schedule_selector(HelloWorld::atualiza));

Para finalizar, adicione esse código no final do arquivo:

void HelloWorld::atualiza(float dt) {

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

}

void HelloWorld::draw() {

CCLayer::draw();

ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position);

kmGLPushMatrix();

HelloWorld::world->DrawDebugData();

kmGLPopMatrix();

}

Agora compile e veja o resultado. Aparecerá um círculo rígido caindo na tela do celular. A Figura 2 mostra o círculo com uma área retangular ao seu redor. O que fizemos no código? Criamos um mundo físico chamado “world” com gravidade igual a 9,78 e adicionamos nele um corpo chamado “corpo”. Definimos esse corpo como “b2_dynamicBody” para que ele não seja um corpo parado, como, por exemplo, um chão. Posicionamos o corpo no espaço exatamente na metade da tela. Notem que eu dividi a coordenada da metade da tela pelo fator de Pixels por Metros (PTM_RATIO). Definimos o corpo como sendo do formato de um círculo e terminamos a construção do mundo físico por aí.

O método “atualiza” é chamado a cada período de tempo para atualizar o mundo físico. Como o corpo que criamos está no ar, sem nenhum lugar para sustentá-lo, ele começa a cair com o passar do tempo. Cada vez que o método “atualiza” é chamado, o mundo físico é atualizado e os corpos que ali estão sofrem a movimentação física conforme o mundo real. Nesse nosso caso, o corpo começa a cair por causa do efeito da gravidade.

Figura 2 - Simulação física executando no celular

Figura 2 – Simulação física executando no celular

Nesse tutorial eu apresentei a vocês a biblioteca de simulação física Box2D. Vimos que para a utilizarmos, precisamos saber alguns conceitos físicos, como o que é um corpo. Vimos que precisamos fazer o debug draw para podermos ver os corpos rígidos no celular e finalmente fizemos uma simulação física simples.

No próximo tutorial eu mostrarei a vocês como incluir mais corpos e fazê-los interagir entre eles e com um chão. Acreditem, vocês não perdem por esperar. =]

Um grande abraço e nos vemos em breve.

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