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

Sistemas articulados geralmente são mais complexos do que apenas um motor e uma polia. Eixos ligados a outros eixos, que são ligados a motores, por exemplo, fazem um sistema articulado ser beeem mais interessante do que apenas um motor e uma polia.

Vamos ver como fazemos isso?

No último tutorial eu mostrei a vocês como fazer um sistema articulado no Box2D, criando uma caixa e uma polia que era ligada na caixa. Essa ligação ocorria por meio de uma articulação que rotacionava com força de 10 Nm e com velocidade máxima de 10 radianos por segundo. Vimos que isso gerou um motor bem legal. Nesse tutorial veremos como incluir mais articulações para fazer um bom uso desse motor. Veremos também um novo tipo de junta: a junta prismática. Bora programar? =]

Primeiramente vamos reutilizar o código do tutorial passado. Caso você não o fez, por favor, clique aqui e pegue o código de lá. Abra o arquivo “HelloWorldScene.cpp” e modifique essa linha de código:

definicaoCorpoCaixaMotor.type = b2_dynamicBody;

para essa:

definicaoCorpoCaixaMotor.type = b2_staticBody;

O que fizemos aqui? Eu transformei a caixa do motor em um objeto estático. Para que isso? Se não transformássemos esse corpo rígido em estático, mais para frente, quando adicionássemos mais elos e juntas na polia, o motor ia ser jogado de um lado para o outro por causa do peso dos elos. Dessa forma, o motor não se movimenta, fazendo com que somente os elos se movimentem com o rotacionar da polia.

Continuando, precisamos fazer com que o motor e a polia que criamos não tenham tratamento de colisão com o sistema articulado. Para isso, vamos fazer com que a caixa do motor, a polia, e os outros eixos da articulação pertençam ao mesmo grupo de objetos que não entram em colisão. Assim, eles não entram nunca em colisão um com o outro. Para isso, adicione a seguinte linha de código:

cascaCaixaMotor.filter.groupIndex = -1;

logo abaixo dessa linha:

cascaCaixaMotor.density = 1.0f;

Acabamos de fazer com que a caixa do motor pertença ao grupo de corpos rígidos “-1”. Precisamos fazer agora com que a nossa polia do tutorial passado também pertença ao mesmo grupo. Para isso, adicione a seguinte linha de código:

cascaPolia.filter.groupIndex = -1;

logo abaixo dessa linha:

cascaPolia.density = 1.0f;

Até agora não criamos nada novo, apenas arrumamos o nosso motor e polia para funcionarem legal com a estrutura que estamos prestes a criar. Continuando, vamos adicionar os elos e as juntas que ficarão presas na polia. A Figura 1 mostra o conjunto completo de como faremos a estrutura articulada.

Figura 1 - Estrutura articulada do motor

Figura 1 – Estrutura articulada do motor

Primeiramente adicionaremos o eixo1 e a junta que o liga à polia. Para isso, logo abaixo dessa linha de código:

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

adicione essas linhas:

b2BodyDef definicaoEixo1;

definicaoEixo1.type = b2_dynamicBody;

definicaoEixo1.position.Set((size.width/2)/PTM_RATIO,5);

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

b2PolygonShape geometriaEixo1;

geometriaEixo1.SetAsBox(2,0.2);

b2FixtureDef cascaEixo1;

cascaEixo1.shape = &geometriaEixo1;

cascaEixo1.density = 1.0f;

cascaEixo1.filter.groupIndex = -1;

corpoEixo1->CreateFixture(&cascaEixo1);

b2RevoluteJointDef definicaoJuntaPoliaEixo1;

definicaoJuntaPoliaEixo1.Initialize(

    corpoPolia,corpoEixo1,b2Vec2((size.width/2)/PTM_RATIO + 1.75,5));

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

Nesse código apenas criamos o eixo 1, o posicionamos no espaço e adicionamos uma junta rotativa para o interligar à polia. Perceba que o eixo 1 está listado como sendo um dos objetos rígidos pertencentes ao grupo “-1”, para que não haja colisão entre ele e o motor. Continuando, vamos adicionar o eixo 2 e outra junta rotativa que o liga ao eixo 1. Logo abaixo, adicione o seguinte código:

b2BodyDef definicaoEixo2;

definicaoEixo2.type = b2_dynamicBody;

definicaoEixo2.position.Set((size.width/2)/PTM_RATIO – 4.5,5);

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

b2PolygonShape geometriaEixo2;

geometriaEixo2.SetAsBox(3,0.2);

b2FixtureDef cascaEixo2;

cascaEixo2.shape = &geometriaEixo2;

cascaEixo2.density = 1.0f;

corpoEixo2->CreateFixture(&cascaEixo2);

b2RevoluteJointDef definicaoJuntaEixo1Eixo2;

definicaoJuntaEixo1Eixo2.Initialize(

    corpoEixo1,corpoEixo2,b2Vec2((size.width/2)/PTM_RATIO – 1.75,5));

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

Finalizaremos por completo o sistema articulado adicionando um objeto para sustentar o eixo 2 e uma junta prismática que liga o eixo 2 ao objeto sustentador. Adicione logo abaixo o seguinte código:

b2BodyDef definicaoSustentador;

definicaoSustentador.type = b2_staticBody;

definicaoSustentador.position.Set((size.width/2)/PTM_RATIO – 3,0);

b2Body* corpoSustentador = HelloWorld::world->CreateBody(&definicaoSustentador);

b2PolygonShape geometriaSustentador;

b2Vec2 pontosSustentador[3] = {

    b2Vec2(1.5,0),

    b2Vec2(-1.5,0),

    b2Vec2(0,6)

};

geometriaSustentador.Set(pontosSustentador,3);

b2FixtureDef cascaSustentador;

cascaSustentador.shape = &geometriaSustentador;

cascaSustentador.density = 1.0f;

corpoSustentador->CreateFixture(&cascaSustentador);

b2PrismaticJointDef definicaoJuntaEixoSustentador;

definicaoJuntaEixoSustentador.Initialize(

    corpoEixo2,corpoSustentador,b2Vec2((size.width/2)/PTM_RATIO – 3,5),b2Vec2(1,0));

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

O que fizemos ali? Criamos um objeto rígido estático que sustentará o eixo 2. Como você pode ver na Figura 1, o eixo 2 deslizará sobre o objeto sustentador, precisando, assim, de uma junta prismática. No código que acabamos de inserir, nós criamos um triângulo como objeto sustentador e uma junta prismática que liga o eixo 2 ao objeto sustentador. Note que a junta prismática serve como se fosse um trilho acoplado no objeto sustentador que o eixo 2 desliza.

Compile o código e o execute. Você verá que o sistema articulado funciona impulsionado pelo motor que rotaciona a polia. Para os curiosos de plantão, como sempre tem, vejam o resultado no vídeo abaixo, também encontrado aqui. Legal o resultado né? =]

Vimos nesse tutorial como incrementar um sistema articulado interligado em um motor. Vimos também que precisávamos incluir um tipo diferente de junta: a prismática. Incluímos a junta prismática para que um objeto rígido pudesse deslizar sobre outro, fazendo possível assim o nosso sistema articulado. No próximo tutorial eu mostrarei um outro tipo de junta: a junta de distância.

É isso aí pessoal. Até o próximo tutorial. Abraço.

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