问题
I have a problem with deleting/creating bodies in libGDX (box2d). I get a fatal error. Log:
http://pastebin.com/fXWXpe8N
I try to destroy bodies after collision. ~90% bodies are deleted good, without errors and crashes. But sometimes it happens. How can I fix this error? I have no idea.
Contact:
private void bulletGround(Contact contact)
{
Body bodyA = null;
Body bodyB = null;
if(contact.getFixtureA() != null && contact.getFixtureA().getUserData() != null &&
contact.getFixtureA().getUserData().equals(Ground.USERDATA))
bodyA = contact.getFixtureA().getBody();
if(contact.getFixtureB() != null && contact.getFixtureB().getUserData() != null &&
contact.getFixtureB().getUserData().equals(Bullet.USERDATA))
bodyB = contact.getFixtureB().getBody();
if(bodyA != null && bodyB != null)
{
if(!world.deletingList.contains(bodyB, true)) {
world.deletingList.add(bodyB);
}
}
}
private void bulletEnemy(Contact contact)
{
Body bodyA = null;
Body bodyB = null;
if(contact.getFixtureA() != null && contact.getFixtureA().getUserData() != null &&
contact.getFixtureA().getUserData().equals(Enemy.USERDATA))
bodyA = contact.getFixtureA().getBody();
if(contact.getFixtureB() != null && contact.getFixtureB().getUserData() != null &&
contact.getFixtureB().getUserData().equals(Bullet.USERDATA))
bodyB = contact.getFixtureB().getBody();
if(bodyA != null && bodyB != null)
{
if(!world.deletingList.contains(bodyB, true) && !world.deletingList.contains(bodyA, true)) {
world.deletingList.add(bodyB);
world.deletingList.add(bodyA);
}
}
}
Deleting:
private void deleteObjects()
{
for (int i = 0; i < gameWorld.deletingList.size; i++) {
Body body = gameWorld.deletingList.get(i);
if (body != null && body.getFixtureList().size > 0 && !gameWorld.getWorld().isLocked())
{
gameWorld.isDeletingTime = true;
body.setUserData(null);
body.setActive(false);
gameWorld.getWorld().destroyBody(body);
gameWorld.deletingList.removeIndex(i);
}
}
gameWorld.isDeletingTime = false;
}
Creating:
render:
if(shootButton.isPressed())
{
if(framesForShoot / Gdx.graphics.getFramesPerSecond() > Info.shootingSpeed)
{
bullet = new Bullet(worldGame, renderer.getGun().getBody().getPosition().x - renderer.angle0fGun,
renderer.getGun().getBody().getPosition().y, renderer.angle0fGun);
renderer.bulletList.add(bullet);
framesForShoot = 0;
}
}
public class Bullet
{
public static final String USERDATA = "bullet";
private GameWorld world;
private Body body;
private Vector2 position;
public Texture bullet_texture;
public Bullet(GameWorld world, float startX, float startY, float pos)
{
this.world = world;
body = this.world.createBox(BodyDef.BodyType.DynamicBody, 0.5f, 0.5f, 0);
body.setTransform(startX, startY, 0);
body.getFixtureList().get(0).setUserData(USERDATA);
bullet_texture = new Texture(Gdx.files.internal("data/bullet.png"));
}
回答1:
I see only one error in you code, I am not sure that it causes the crash, but you should fix it in any way.
gameWorld.deletingList.removeIndex(i);
You must not remove items from array in the same time you looping thru the same array. This can result to unpredictable bugs, because every time you remove item, the array will change items order and decrease size. The solution is to create temporary array and loop thru it, so you will be able to remove items from original one.
Also where do you call your deleteObjects()
? You should call in render()
, after world.step()
and not in beginContact()
or endContact
().
来源:https://stackoverflow.com/questions/26082439/deleting-and-creating-body-in-libgdx