Tutorial: Desenvolvendo um jogo de guiar bolinha em labirinto – Parte 3: Criando as paredes

Fizemos a bolinha andar na tela de acordo com a angulação do celular em relação ao chão.

Isso fazia, no entanto, a bolinha sair da tela do aparelho.

Não sentiu falta do cenário em si? Vamos implementá-lo?

No tutorial passado nós implementamos toda a física que movimenta a bolinha na tela. Vimos como decompor a força da gravidade em duas outras forças. Uma delas é desconsiderada enquanto a outra é aplicada constantemente no objeto rígido que representa a bolinha de aço. Vimos que essa força sofre variação de acordo com a angulação do aparelho nos eixos X e Y.

Com isso, já temos a física do jogo toda funcionando. Basta incluirmos o cenário para que tenhamos a primeira versão jogável do nosso game. Incluiremos nesse tutorial uma série de objetos rígidos em formato de caixas para fazer as paredes do nosso labirinto. Esses objetos rígidos são criados no mundo do Box2D como objetos estáticos, ou seja, eles não sofrem ação da gravidade nem de outros objetos que colidem com eles. Em outras palavras, adicionaremos paredes estáticas em forma de retângulos ao iniciarmos a construção do nosso cenário.

Para isso, abra o arquivo “HelloWorldScene.cpp”, modificado no tutorial passado. Se você não fez o tutorial passado, faça-o para que possamos continuar de onde paramos. No arquivo aberto, logo abaixo dessa linha de código:

HelloWorld::bolinha->CreateFixture(&cascaBolinha);

adicione essas linhas:

b2BodyDef definicaoParedes;

definicaoParedes.type = b2_staticBody;

b2Body* paredes = HelloWorld::mundo->CreateBody(&definicaoParedes);

b2Vec2 vParedes[4];

vParedes[0].Set((size.width/PTM_RATIO)/2 – (426.0/PTM_RATIO)/2,(size.height/PTM_RATIO)/2 – (320.0/PTM_RATIO)/2);

vParedes[1].Set((size.width/PTM_RATIO)/2 + (426.0/PTM_RATIO)/2,(size.height/PTM_RATIO)/2 – (320.0/PTM_RATIO)/2);

vParedes[2].Set((size.width/PTM_RATIO)/2 + (426.0/PTM_RATIO)/2,(size.height/PTM_RATIO)/2 + (320.0/PTM_RATIO)/2);

vParedes[3].Set((size.width/PTM_RATIO)/2 – (426.0/PTM_RATIO)/2,(size.height/PTM_RATIO)/2 + (320.0/PTM_RATIO)/2);

b2ChainShape geometriaParedes;

geometriaParedes.CreateLoop(vParedes,4);

b2FixtureDef cascaParedes;

cascaParedes.shape = &geometriaParedes;

paredes->CreateFixture(&cascaParedes);

b2Body* caixas[6];

b2BodyDef definicaoCaixas0;

definicaoCaixas0.position.Set((size.width/PTM_RATIO)/2,(size.height/PTM_RATIO)/2 – 80.0/PTM_RATIO);

definicaoCaixas0.type = b2_staticBody;

caixas[0] = HelloWorld::mundo->CreateBody(&definicaoCaixas0);

b2PolygonShape geometriaCaixas0;

geometriaCaixas0.SetAsBox(144.0/PTM_RATIO,16.0/PTM_RATIO);

b2FixtureDef cascaCaixas0;

cascaCaixas0.shape = &geometriaCaixas0;

caixas[0]->CreateFixture(&cascaCaixas0);

b2BodyDef definicaoCaixas1;

definicaoCaixas1.position.Set((size.width/PTM_RATIO)/2,(size.height/PTM_RATIO)/2 + 80.0/PTM_RATIO);

definicaoCaixas1.type = b2_staticBody;

caixas[1] = HelloWorld::mundo->CreateBody(&definicaoCaixas1);

b2PolygonShape geometriaCaixas1;

geometriaCaixas1.SetAsBox(144.0/PTM_RATIO,16.0/PTM_RATIO);

b2FixtureDef cascaCaixas1;

cascaCaixas1.shape = &geometriaCaixas1;

caixas[1]->CreateFixture(&cascaCaixas1);

b2BodyDef definicaoCaixas2;

definicaoCaixas2.position.Set((size.width/PTM_RATIO)/2 + 128.0/PTM_RATIO,(size.height/PTM_RATIO)/2);

definicaoCaixas2.type = b2_staticBody;

caixas[2] = HelloWorld::mundo->CreateBody(&definicaoCaixas2);

b2PolygonShape geometriaCaixas2;

geometriaCaixas2.SetAsBox(16.0/PTM_RATIO,64.0/PTM_RATIO);

b2FixtureDef cascaCaixas2;

cascaCaixas2.shape = &geometriaCaixas2;

caixas[2]->CreateFixture(&cascaCaixas2);

b2BodyDef definicaoCaixas3;

definicaoCaixas3.position.Set((size.width/PTM_RATIO)/2 – 128.0/PTM_RATIO,(size.height/PTM_RATIO)/2 – 32.0/PTM_RATIO);

definicaoCaixas3.type = b2_staticBody;

caixas[3] = HelloWorld::mundo->CreateBody(&definicaoCaixas3);

b2PolygonShape geometriaCaixas3;

geometriaCaixas3.SetAsBox(16.0/PTM_RATIO,32.0/PTM_RATIO);

b2FixtureDef cascaCaixas3;

cascaCaixas3.shape = &geometriaCaixas3;

caixas[3]->CreateFixture(&cascaCaixas3);

b2BodyDef definicaoCaixas4;

definicaoCaixas4.position.Set((size.width/PTM_RATIO)/2 + 48.0/PTM_RATIO,(size.height/PTM_RATIO)/2 – 32.0/PTM_RATIO);

definicaoCaixas4.type = b2_staticBody;

caixas[4] = HelloWorld::mundo->CreateBody(&definicaoCaixas4);

b2PolygonShape geometriaCaixas4;

geometriaCaixas4.SetAsBox(16.0/PTM_RATIO,32.0/PTM_RATIO);

b2FixtureDef cascaCaixas4;

cascaCaixas4.shape = &geometriaCaixas4;

caixas[4]->CreateFixture(&cascaCaixas4);

b2BodyDef definicaoCaixas5;

definicaoCaixas5.position.Set((size.width/PTM_RATIO)/2 – 48.0/PTM_RATIO,(size.height/PTM_RATIO)/2 + 32.0/PTM_RATIO);

definicaoCaixas5.type = b2_staticBody;

caixas[5] = HelloWorld::mundo->CreateBody(&definicaoCaixas5);

b2PolygonShape geometriaCaixas5;

geometriaCaixas5.SetAsBox(16.0/PTM_RATIO,32.0/PTM_RATIO);

b2FixtureDef cascaCaixas5;

cascaCaixas5.shape = &geometriaCaixas5;

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

de forma que, no final da função, fiquem essas três linhas de código:

setAccelerometerEnabled(true);

schedule(schedule_selector(HelloWorld::atualiza));

return true;

O que fizemos nesse momento? Acabamos de adicionar quatro linhas que representam as paredes exteriores do nosso labirinto e um total de 6 caixas que representam as paredes internas do nosso labirinto. Notem que cada um desses objetos rígidos são objetos estáticos e, caso a bolinha colida com eles, eles não sofrerão qualquer movimentação. Compile o código e execute o jogo. Temos a nossa primeira versão jogável do game. Para os curiosos de plantão, a Figura 1 mostra o jogo executando.

Figura 1 - Jogo executando

Figura 1 – Jogo executando

Esse tutorial foi simples. O objetivo dele foi adicionar paredes para que tenhamos uma primeira versão do cenário. Adicionaremos em tutoriais futuros mais alguns elementos, como a boca de objetivo e bocas em que a bola não poderá cair. No próximo tutorial, porém, incluiremos uma camada de imagens e Sprites para deixar o jogo um pouco mais parecido com um labirinto de madeira contendo uma bola de aço.

Por hoje é isso pessoal, 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