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

Um dos principais motivos para você achar legal a simulação física é a possibilidade de programar objetos articulados.

Acredite, animações de seres humanos, aranhas ou motores deixam o seu aplicativo muito interessante.

O que você acha de vermos como isso funciona?

Vimos no último tutorial que você não precisa ter conhecimentos específicos de física para fazer uma simulação legal. Também programamos um ambiente que gerava corpos rígidos e eles se adaptavam em um espaço fechado, conforme o seu peso e geometria.

Nesse tutorial veremos uma parte de como criamos objetos articulados no motor físico Box2D. Existem vários tipos de articulação (juntas) e eu pretendo passar para vocês como programar as principais. Então … mãos à obra.

Articulações

Antes de sairmos programando, é preciso que vocês tenham ideia do que se trata uma articulação. Uma articulação (chamarei algumas vezes de junta) é utilizada para ligar corpos rígidos. Alguns exemplos de articulações são esqueletos, polias, pêndulos, e por aí vai. No seu aplicativo, você pode combinar vários tipos de articulações e fazer algumas animações bem legais. Existem vários tipos de articulações no Box2D, mas eu falarei apenas sobre algumas:

  • Junta de distância: essa é uma das articulações mais simples do Box2D. Ela especifica uma distância padrão entre dois pontos de dois corpos. A Figura 1 ilustra a explicação.

Figura 1 - Junta de distância

Figura 1 – Junta de distância

  • Junta rotativa: uma junta rotativa força dois corpos a estarem presos em um único ponto. Um corpo pode sofrer rotação em relação à outro, mas eles ficam presos sempre no mesmo lugar. A Figura 2 mostra a explicação.

Figura 2 - Junta rotativa

Figura 2 – Junta rotativa

  • Junta prismática: a junta prismática provê que dois corpos deslizem entre si em um certo eixo. Lembra um ponto que anda sobre um trilho. A Figura 3 mostra a explicação dada.

Figura 3 - Junta prismática

Figura 3 – Junta prismática

  • Junta pendular: essa articulação ajuda o programador a criar um pêndulo. Uma ponta do pêndulo pode ficar presa em um corpo e a outra presa em um lugar qualquer do mundo do Box2D. Segue a Figura 4 para ilustração.

Figura 4 - Junta pendular

Figura 4 – Junta pendular

Se vocês quiserem saber mais sobre outros tipos de articulações, pesquisem no próprio manual do Box2D. Na verdade tudo o que você quiser saber sobre a biblioteca, tem lá. ;D

 

Implementação de uma Junta Rotativa

Começaremos criando um novo aplicativo Cocos2d-x. Se você não lembra como, veja esse tutorial. Lembre-se de adicionar os arquivos para debug draw. Se você não lembra como, veja nesse tutorial. Como estamos novamente criando uma simulação do zero, precisamos reconfigurar o debug draw.

Abra o arquivo “HelloWorldScene.cpp” e apague todo o código, partindo dessas linhas (inclusive):

// add “HelloWorld” splash screen”

CCSprite* pSprite = CCSprite::create(“HelloWorld.png”);

até essa linha (inclusive):

this->addChild(pSprite, 0);

No mesmo lugar onde você apagou o código, adicione esse trecho:

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 definicaoChao;

definicaoChao.type = b2_staticBody;

b2Body* corpoChao = HelloWorld::world->CreateBody(&definicaoChao);

b2EdgeShape geometriaChao;

geometriaChao.Set(b2Vec2(0.0f,0.0f),b2Vec2(size.width/PTM_RATIO,0.0f));

b2FixtureDef cascaChao;

cascaChao.shape = &geometriaChao;

corpoChao->CreateFixture(&cascaChao);

b2BodyDef definicaoCorpoCaixaMotor;

definicaoCorpoCaixaMotor.type = b2_dynamicBody;

definicaoCorpoCaixaMotor.position.Set((size.width/2)/PTM_RATIO + 5,3);

b2Body* corpoCaixaMotor = HelloWorld::world->CreateBody(&definicaoCorpoCaixaMotor);

b2PolygonShape geometriaCaixaMotor;

geometriaCaixaMotor.SetAsBox(3,3);

b2FixtureDef cascaCaixaMotor;

cascaCaixaMotor.shape = &geometriaCaixaMotor;

cascaCaixaMotor.density = 1.0f;

corpoCaixaMotor->CreateFixture(&cascaCaixaMotor);

b2BodyDef definicaoCorpoPolia;

definicaoCorpoPolia.type = b2_dynamicBody;

definicaoCorpoPolia.position.Set((size.width/2)/PTM_RATIO + 3,5);

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

b2CircleShape geometriaPolia;

geometriaPolia.m_radius = 1.5;

b2FixtureDef cascaPolia;

cascaPolia.shape = &geometriaPolia;

cascaPolia.density = 1.0f;

corpoPolia->CreateFixture(&cascaPolia);

b2RevoluteJointDef definicaoJuntaPolia;

definicaoJuntaPolia.Initialize(corpoCaixaMotor,corpoPolia,corpoPolia->GetWorldCenter());

definicaoJuntaPolia.maxMotorTorque = 10.0f;

definicaoJuntaPolia.motorSpeed = 10.0f;

definicaoJuntaPolia.enableMotor = true;

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

schedule(schedule_selector(HelloWorld::atualiza));

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 abra o arquivo HelloWorldScene.h, e adicione esse código:

#include “Box2D/Box2D.h”

#include “B2DebugDrawLayer.h”

#define PTM_RATIO 40

logo abaixo dessa linha:

#define __HELLOWORLD_SCENE_H__

Adicione no mesmo arquivo esse trecho de código:

void atualiza(float dt);

B2DebugDrawLayer* debugDrawLayer;

b2World* world;

virtual void draw();

abaixo dessa linha:

CREATE_FUNC(HelloWorld);

Compile-o e o execute. Você verá uma caixa que eu criei como sendo um motor. No código, você pode ver essa caixa pelo corpo rígido nomeado “corpoCaixaMotor”. Nessa caixa, eu adicionei um círculo que seria a polia que o motor roda. Você pode encontrar esse corpo rígido procurando o objeto nomeado “corpoPolia”. Após eu criar o chão, o motor e a polia, eu criei uma articulação exatamente no centro da polia que a interligava na caixa do motor. Criei essa articulação com o método “CreateJoint”. Note que antes de eu criar a articulação, que nesse caso foi uma junta rotativa, eu também adicionei um motor nela que faz a polia girar. Esse motor possui 10 Nm (newton metros), que é uma unidade de torque (força do motor). Percebam também que eu o fiz rodar na velocidade de 10 radianos por segundo (velocidade do motor). O resultado é mostrado na Figura 5.

Figura 5 - Motor girando uma polia no Box2D

Figura 5 – Motor girando uma polia no Box2D

Apresentei a vocês nesse tutorial alguns tipos de articulações que o motor gráfico Box2D proporciona. Implementamos uma polia ligada a um motor que a gira com uma certa quantidade de força (torque) e velocidade final. No próximo tutorial eu mostrarei a vocês um outro tipo de articulação: a junta prismática.

Um grande abraço pessoal 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