Tutorial: Criando um jogo de car parking – Parte 2: Criando o mundo físico no Box2D

Demos o pontapé inicial no desenvolvimento de mais um game.

Colocamos as imagens dos objetos do jogo na tela, porém ele ainda é uma imagem estática e sem qualquer funcionalidade.

Hoje iniciaremos a implementação do sistema de colisão do nosso game de estacionar carros.

No último tutorial nós vimos como funciona um game ao estilo car parking, criamos o projeto do nosso próximo jogo no Cocos2d-x e incluímos alguns Sprites na tela para vermos como ficará o game. Nesse tutorial nós daremos início à implementação da parte lógica. Criaremos um mundo físico do Box2D e incluiremos nele os objetos rígidos que representam os dois carros posicionados no tutorial anterior e de mais um carro que será aquele que o jogador terá o controle. Partiu código. =]

Antes de tudo, vale lembrar que, para você dar início a esse tutorial, é necessário que você faça o tutorial passado. Abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:

#include “Box2D/Box2D.h”

#define PTM_RATIO 40

logo abaixo dessa:

#define __HELLOWORLD_SCENE_H__

Ainda no mesmo arquivo, adicione as seguintes linhas de código:

b2World* mundoFisico;

cocos2d::CCSprite* carroJogador;

b2Body* corpoCarroJogador;

logo abaixo dessa:

static cocos2d::CCScene* scene();

O que fizemos nesse trecho? Primeiramente, abrimos a biblioteca do Box2D e criamos uma constante global chamada “PTM_RATIO”. Para quem não lembra ou não sabe qual o motivo dela existir, ela serve para termos uma proporção entre pixels da tela do celular e distância em metros. Como o Box2D trabalha somente com a unidade de medida metros, então precisa-se dela para sabermos quantos pixels equivalem a um metro. Nesse caso, como o valor dessa constante é 40, então sabemos que 40 pixels da tela do aparelho equivalem a um metro do ambiente do Box2D. Também criamos três variáveis que serão importantes para o jogo: uma que referencia o mundo físico do Box2D, chamada “mundoFisico”; uma que referencia o Sprite do carro do jogador, chamada “carroJogador”, e uma que referencia o corpo rígido do carro do jogador, chamada “corpoCarroJogador”. Não precisamos modificar mais nada nesse arquivo, apenas salve-o.

Agora abra o arquivo “HelloWorldScene.cpp” e adicione as seguintes linhas de código:

HelloWorld::carroJogador = CCSprite::createWithSpriteFrameName(“Carro.png”);

HelloWorld::carroJogador->setScale((0.3*size.height)/HelloWorld::carroJogador->boundingBox().size.width);

HelloWorld::carroJogador->setPosition(ccp(0.1*size.width,0.2*size.height));

HelloWorld::carroJogador->setRotation(-90);

addChild(HelloWorld::carroJogador);

HelloWorld::mundoFisico = new b2World(b2Vec2(0,0));

b2BodyDef definicaoCarro1;

definicaoCarro1.position.Set(carro1->getPositionX()/PTM_RATIO,carro1->getPositionY()/PTM_RATIO);

definicaoCarro1.type = b2_staticBody;

b2Body* corpoCarro1 = HelloWorld::mundoFisico->CreateBody(&definicaoCarro1);

b2PolygonShape geometriaCarro1;

geometriaCarro1.SetAsBox((carro1->boundingBox().size.width/PTM_RATIO)/2,(carro1->boundingBox().size.height/PTM_RATIO)/2);

b2FixtureDef cascaCarro1;

cascaCarro1.shape = &geometriaCarro1;

corpoCarro1->CreateFixture(&cascaCarro1);

b2BodyDef definicaoCarro2;

definicaoCarro2.position.Set(carro2->getPositionX()/PTM_RATIO,carro2->getPositionY()/PTM_RATIO);

definicaoCarro2.type = b2_staticBody;

b2Body* corpoCarro2 = HelloWorld::mundoFisico->CreateBody(&definicaoCarro2);

b2PolygonShape geometriaCarro2;

geometriaCarro2.SetAsBox((carro2->boundingBox().size.width/PTM_RATIO)/2,(carro2->boundingBox().size.height/PTM_RATIO)/2);

b2FixtureDef cascaCarro2;

cascaCarro2.shape = &geometriaCarro2;

corpoCarro2->CreateFixture(&cascaCarro2);

b2BodyDef definicaoCarroJogador;

definicaoCarroJogador.type = b2_dynamicBody;

HelloWorld::corpoCarroJogador = HelloWorld::mundoFisico->CreateBody(&definicaoCarroJogador);

HelloWorld::corpoCarroJogador->SetTransform(b2Vec2(HelloWorld::carroJogador->getPositionX()/PTM_RATIO,HelloWorld::carroJogador->getPositionY()/PTM_RATIO),M_PI/2);

b2PolygonShape geometriaCarroJogador;

geometriaCarroJogador.SetAsBox((HelloWorld::carroJogador->boundingBox().size.height/PTM_RATIO)/2,(HelloWorld::carroJogador->boundingBox().size.width/PTM_RATIO)/2);

b2FixtureDef cascaCarroJogador;

cascaCarroJogador.shape = &geometriaCarroJogador;

HelloWorld::corpoCarroJogador->CreateFixture(&cascaCarroJogador);

logo abaixo dessa:

addChild(cima);

Nesse último código incluso, nós primeiramente adicionamos um Sprite de um novo carro, que será aquele que o jogador controlará. Depois criamos o mundo físico do Box2D sem gravidade. Isso porque o jogo tem visão superior, o que faz com que o carro já esteja encostado no chão, segundo a perspectiva da câmera do jogo. Logo após, nós criamos dois objetos rígidos estáticos em forma de caixa, e os posicionamos exatamente sobre os dois carros estacionados. Fizemos esses objetos estáticos para que eles não se movimentem caso o jogador bata com o carro neles. Por último, criamos o corpo rígido do carro que o jogador tem o controle e o posicionamos sobre o Sprite do carro do jogador. Esse corpo rígido é um corpo dinâmico, pois ele sofrerá movimentação durante a simulação física. Note que, futuramente, o Sprite do carro do jogador acompanhará a posição e a angulação do corpo desse último corpo rígido adicionado. A Figura 1 mostra logicamente como está o jogo e também onde estão os corpos rígidos que adicionamos no ambiente do Box2D.

Figura 1 - Corpos rígidos adicionados no jogo

Figura 1 – Corpos rígidos adicionados no jogo

Adicionamos nesse tutorial um mundo físico do Box2D, que simulará o nosso game e criamos três corpos rígidos nesse mundo. Cada corpo rígido representará um carro, sendo que dois são estáticos e um é dinâmico. Os corpos rígidos estáticos não sofrerão movimentação pelo fato deles representarem os carros estacionados, enquanto que o corpo que sofre movimentação representará o carro que o jogador manipulará. No próximo tutorial incluiremos outros corpos rígidos que representarão as rodas do carro do jogador e faremos essas rodas darem a direção do carro e o fazem movimentar.

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