Recebo este erro ao tentar remover um corpo do mundo:
java: /var/lib/hudson/jobs/libgdx/workspace/trunk/gdx/jni/Box2D/Dynamics/b2World.cpp:134: void b2World :: DestroyBody (b2Body *): asserção 'IsLocked () == false' falhou.
O que estou fazendo errado?
Respostas:
Da minha pouca experiência com o box2d na libgdx, às vezes pode ser difícil isolar e resolver problemas com exceções que só foram agravadas pela última porta. Antes da 2.2.1, eu podia remover facilmente corpos do mundo sem problemas de sincronização, como você está enfrentando, mas depois de migrar para a libgdx build que suportava a 2.2.1, comecei a ver os mesmos problemas. A solução alternativa para mim, sugerida por várias pessoas, foi que você não pode remover corpos do mundo enquanto o mundo estiver sendo simulado.
Existe a possibilidade de você tentar remover um corpo do mundo quando o mundo está sendo pisado? Basicamente, se você tentar fazer isso, o box2d não gosta, então o que você precisa fazer é remover os corpos fora do
world.step
. O que fiz foi adicionar uma classe de utilidade para o corpo.userData
com um bool isFlaggedForDelete que seria verificado fora do método world.step.Se você executar algo assim logo após o seu world.step, ele deverá funcionar. No seu código em que você está tentando destruir o corpo, defina-o como .isFlaggedForDelete como true e ele será removido antes do próximo world.step.
fonte
sweepDeadBodies
método proposto aqui desperdiça muitos ciclos percorrendo os corpos que não serão excluídos. Nesses casos, considere enviar ponteiros para os corpos a serem destruídos em umadeadBodies
lista em um escopo externo e, em seguida, iterá- lo após astep
limpeza e limpá-lo uma vez feito.Então, temos o seu erro:
Vamos dividir:
A maior parte da primeira parte desse erro são instruções úteis para informar onde o erro está ocorrendo.
Parece que o erro está sendo gerado em um arquivo de origem chamado b2World.cpp dentro da estrutura de diretórios mostrada. E está acontecendo:
Na linha 134.
Então parece,
a função b2World: DestroyBody () que retorna
void
e aceita um ponteiro para ab2Body
está relatando o erro.Isso terminou a parte "where" do erro, agora está nos dizendo o "what". Parece que está tentando afirmar que
isLocked()
é igual afalse
Mas está falhando.
Agora nunca usei o Box2D, mas acho que isso significa que o corpo que você está tentando destruir está trancado. Você precisará descobrir por que o corpo está bloqueado e como desbloqueá-lo.
fonte
A implementação do Libgdx é apenas uma ponte para a versão nativa, portanto todas as mesmas regras se aplicam.
Nunca tente remover um corpo / acessório / junta quando a simulação estiver em execução.
Nunca tente remover um corpo / acessório / articulação mais de uma vez.
Nunca deixe ponteiros (também conhecidos como referências) para acessórios ou juntas ao excluir o corpo.
Para ser mais cauteloso - talvez até um pouco paranóico - eu uso esse método para remover meus corpos:
fonte
Esta é a melhor maneira de fazer isso, eu li no manual do Box2D. Você deve chamar isso logo após CURRENT_WORLD.step (.., ..., ...);
fonte
O erro diz tudo, você precisa verificar se o mundo está bloqueado no momento em que você deseja remover o corpo
que funcionou para mim :)
fonte