quarta-feira, 29 de maio de 2013 0 comentários

Box2D erro ou error no destroyBody

E hoje estava lá brincando com meu Box2D (uma biblioteca de física para games) gastei o dia todo estudando ele, sabe o que é nem sair para comer? Em fim, trombei com um erro que consegui driblar, mas que não sei se é o jeito correto. Se alguém souber um jeito melhor poste nos comentário.

Código
//Método que verifica uma colisão no jBox2D
public void verificarColisao(){

//Step é o que faz o mundo andar 
mundo.step(0.1f, 6, 2);

//Método que verifica a colisão de 2 corpos 
mundo.setContactListener(new ContactListener(){


//Se houve um contato cai aqui
public void beginContact(Contact contact) {

//Captura os 2 corpos que fizeram contato atribuindo a um Objeto Corpo
Body corpoA = contact.getFixtureA().getBody();
Body corpoB = contact.getFixtureB().getBody();  
 
//Verifica se os corpos são do tipo Bola, poderia ser de tipos distintos como Bala e Garrafa, mas aqui são 2 bolas que irão se explodir ao se tocarem
 if((corpoA.getUserData().equals("Bola") &&
 corpoB.getUserData().equals("Bola")) ||
 (corpoB.getUserData().equals("Bola") && 
 corpoA.getUserData().equals("Bola")) 
 ){
//Aqui que mora o problema, se usarmos mundo.destroyBody(corpoA); irá gerar um erro. O motivo acredito seja porque ainda esteja em meio a testes de colisão. Para consertar isso adicionei os corpos que desejo remover em uma Matriz Array chamada de corposRemove e no final do código mando passar por todos os corpos que desejo remover.

  corposRemove.add(corpoA);
  corposRemove.add(corpoB);
 
}

@Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
Gdx.app.log("Aviso:", "Fim do contato");
}

@Override
public void preSolve(Contact contact, Manifold oldManifold) {
// TODO Auto-generated method stub

}

@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
// TODO Auto-generated method stub

}

});

              //Podemos colocar um If aqui para ver se há corpos que desejamos retirar a fim de evitar processo desnecessário, passamos pela lista de corpos e se acharmos algumo destruimos .
for(int i =0; i < corposRemove.size; i++){
 mundo.destroyBody(corposRemove.get(i));
 corposRemove.removeIndex(i);
}.
}


Bom, como pudemos ver para se remover um corpo de forma correta devemos destrui-lo após ter saido das verificações de colisão. Um private Iterator corpos; poderia tb dar a ilusão de ter removido um corpo dentro do jogo, mas tudo o que fazemos é remover a fixture dele mantendo o corpo dentro do World ... É necessario sua destruição para bom funcionamento do jogo. Não esqueça também de chamar o dispose da textura usada, para liberar memória. Até a próxima :)
 
;