25%OFF no 1º ano | 50%OFF No 2º ano

Tá acabando!

Tá acabando!

00

HORAS

00

MIN

00

SEG

Física em jogos com Chipmunk2D

Física em jogos com Chipmunk2D
vitor.mattos
vitor.mattos

Compartilhe

Uma dúvida de muitos que iniciam no desenvolvimento de jogos é: "Como farei para simular a física?" Lidar com física nunca é uma tarefa simples. Temos que considerar gravidade, como ela afeta os corpos presentes no espaço, colisão entre os corpos, força de impulso, formas geométricas etc.

chipmunk

Para que o desenvolvedor não precise se preocupar com todos esses aspectos, diversas engines de física para jogos foram criados. Veremos o quão fácil é trabalhar com a engine Chipmunk2D, usando o framework Cocos2d-JS para criar nosso jogo! Você pode conferir o resultado final do que faremos nesse link.

jogo

Diversos tutoriais básicos sobre Cocos2d podem ser encontrados na página da documentação e o download está disponível aqui.

Banner da prorrogação da Black Friday da Alura. Transforme a sua carreira com o maior desconto do ano, matricule-se já!

Para começarmos a usar a engine de física do Chipmunk2D, temos que declarar nas configurações do Cocos2d-JS que usaremos o chipmunk. Para isso, alteramos o arquivo cocos2d.js na pasta cocos2d e adicionamos a seguinte instrução:

 chipmunk:true, 

Agora toda vez que carregarmos o Cocos2d, o jsloader carregará também a biblioteca do Chipmunk2D.

Para de fato usarmos a física em uma cena, precisamos de um objeto chamado Space. Nesse objeto definiremos todas as regras de física do nosso "espaço", como a gravidade, por exemplo. É comum criarmos um método (initPhysics) na cena (Scene) que iniciará todas as configurações de física:

 var PhysicScene = cc.Scene.extend({ space: null,

initPhysics:function() { //criação do objeto Space this.space = new cp.Space(); },

onEnter:function () { this.\_super(); this.initPhysics(); var layer = new GameLayer(this.space); this.addChild(layer);

this.scheduleUpdate(); }, update: function(dt) { this.space.step(dt); } }); 

Pronto! Agora já temos um objeto representando o espaço. Um vez criado podemos definir a força da gravidade nele. Para tal, o objeto space possui uma propriedade gravity que recebe um vetor no plano cartesiano:

 //dentro da função initPhysics, logo após ter criado o space this.space.gravity = cp.v(0, -650); 

O próximo passo é criar um GameLayer. Nesse Layer (ou camada da cena) acontecerão todas as animações. É a camada principal que junta todos os elementos do jogo.

O GameLayer recebe o objeto space criado anteriormente como parâmetro no construtor. O código seguinte initializa o GameLayer:

 var GameLayer = cc.Layer.extend({

ctor : function(space){ this.\_super(); this.space = space; this.init(); },

init:function(){ this.\_super(); //aqui vamos fazer mais coisas ainda }, }); 

Vamos simular um corpo sendo afetado pela gravidade em nosso espaço. Representaremos esse corpo com o sprite de uma bola que fica salvo dentro de um diretório especial chamado res/Normal/:

ball

Para a simulação, no GameLayer dentro da função init criaremos o sprite da bola e o associaremos a um corpo físico:

 init:function(){ this.\_super();

// cc.PhysicsSprite cria um sprite que representará um corpo var bola = cc.PhysicsSprite.create("ball.png"); this.addChild(bola);

var raio = 32;

// Criando o corpo físico que obedecerá as leis do espaço var corpo = this.space.addBody(new cp.Body(10, cp.momentForCircle(10, 0, raio, cp.v(0,0))));

// Podemos escolher a forma do corpo, a elasticidade e a fricção dele! forma = this.space.addShape(new cp.CircleShape(corpo, raio, cp.v(0,0))); forma.setElasticity(0.6); forma.setFriction(1);

var s = cc.Director.getInstance().getWinSize(); corpo.setPos(cp.v(s.width/2, s.height/2));

bola.setBody(corpo) }, 

Rode a aplicação e verifique o resultado. A bola está passando desaparecendo tela! Precisamos criar um chão para que ela permaneça na área visível.

Vamos criar 4 paredes, uma em cada lado da tela, transformando a área jogável em uma espécie de "caixa". No método initPhysics, que está no PhysicScene:

 var winSize = cc.Director.getInstance().getWinSize();

var staticBody = this.space.staticBody;

var paredes = \[ new cp.SegmentShape(staticBody, cp.v(0,0), cp.v(winSize.width,0), 0 ), // bottom

new cp.SegmentShape(staticBody, cp.v(0,winSize.height), cp.v(winSize.width,winSize.height), 0), // top

new cp.SegmentShape(staticBody, cp.v(0,0), cp.v(0,winSize.height), 0), // left

new cp.SegmentShape(staticBody, cp.v(winSize.width,0), cp.v(winSize.width,winSize.height), 0) // right \];

for( var i=0; i < paredes.length; i++ ) { var forma = paredes\[i\]; forma.setElasticity(1); forma.setFriction(1); this.space.addStaticShape( forma ); } 

Agora nossa bola bate no chão e quica! Podemos facilmente aplicar um impulso ao corpo. Na função init do GameLayer:

 var forcaX = -4000; var forcaY = 3000;

corpo.applyImpulse(cp.v(forcaX, forcaY), cp.v(0, 0)); 

Agora a bola começa já com um impulso. O primeiro parâmetro da função applyImpulse é um vetor com a direção do impulso. O segundo parâmetro é um offset indicando (a partir do centro do corpo) onde o impulso será aplicado. Poderíamos usar valores diferentes de 0 se quiséssemos causar uma rotação na bola.

Vimos que é muito simples simularmos física em nossos jogos do Cocos2d-html5 usando a engine Chipmunk2D. Só precisamos de um objeto space, onde podemos configurar, por exemplo, a gravidade. E nele teremos os corpos que serão afetados pela física.

Falta mencionar que Cocos2d já vem com o Cocos2d-html5 e o Cocos2d-x Javascript Binding, para podermos compilar nosso código para rodar nativamente em dispositivos mobile. Além disso, a biblioteca do Cocos2d também possui suporte para outras engines de física, como por exemplo o Box2D.

O código completo desse projeto pode ser encontrado no Github e se quiser saber mais sobre Cocos2d-html5, não deixe de visitar a MobileConf RJ 2014!

Veja outros artigos sobre Front-end