error, how to remove BOX2D

I got an error, when I launch fireball too swiftly, I guess, my fireball does not really remove well. So that's why I got crush.. Can you guys check my update method, and please give me some idea?

And one more thing I want know is what !world.isLocked() means...

public class FireBall extends Sprite {

PlayScreen screen;
World world;
Array<TextureRegion> frames;
Animation fireAnimation;
float stateTime;
float firetiem;
public static  boolean destroyed;
boolean setToDestroy;
boolean fireRight;

public static Body b2body;
public FireBall(PlayScreen screen, float x, float y, boolean fireRight){
this.world = screen.getWorld();
this.fireRight = fireRight;
this.screen = screen;
destroyed = false;
frames = new Array<TextureRegion>();
for(int i = 0; i < 4; i++){
frames.add(new TextureRegion(screen.getAtlas().findRegion("fireball"), i * 8, 0, 8, 8));
}
fireAnimation = new Animation(0.2f, frames);
setRegion((TextureRegion)fireAnimation.getKeyFrame(0));
setBounds(x, y, 6 / MarioBros.PPM, 6 / MarioBros.PPM);
defineFireBall();
}

public void defineFireBall(){
BodyDef bdef = new BodyDef();
bdef.position.set(fireRight ? getX() + 12 /MarioBros.PPM   :  getX() - 12 /MarioBros.PPM, getY());
bdef.type = BodyDef.BodyType.DynamicBody;
if(!world.isLocked())
b2body = world.createBody(bdef);//?

FixtureDef fdef = new FixtureDef();
CircleShape shape = new CircleShape();
fdef.filter.categoryBits = MarioBros.FIREBALL_BIT;
MarioBros.COIN_BIT |
MarioBros.BRICK_BIT |
MarioBros.ENEMY_BIT|
MarioBros.OBJECT_BIT;

fdef.shape = shape;
fdef.restitution = 1;
fdef.friction = 0;
b2body.setLinearVelocity(new Vector2(fireRight ? 2 : -2, 2.5f));
b2body.createFixture(fdef).setUserData(this);

}

public void update(float dt){
stateTime += dt;

setRegion((TextureRegion) fireAnimation.getKeyFrame(stateTime, true));
setPosition(b2body.getPosition().x - getWidth() / 2, b2body.getPosition().y - getHeight() / 2);

if((stateTime > 0.5f &&  !destroyed)) {
System.out.println("remove");
world.destroyBody(b2body);
destroyed = true;
stateTime=0;
}

if(b2body.getLinearVelocity().y > 2f)
b2body.setLinearVelocity(b2body.getLinearVelocity().x, 2f);

}

public boolean isDestroyed(){
return destroyed;
}}

• ! is the not operator; assuming the method in question returns what its name suggests, the code !world.isLocked() means 'when the world is not locked'. – Pikalek Sep 29 '17 at 2:39

It looks like you're accessing your Body after it has been destroyed, that is not allowed.

Try returning immediately from the update method if destroyed is set, and make sure destroying the Body is the last thing that happens in that method.

public void update(float dt){
if(destroyed)
return;
stateTime += dt;

setRegion((TextureRegion) fireAnimation.getKeyFrame(stateTime, true));
setPosition(b2body.getPosition().x - getWidth() / 2, b2body.getPosition().y - getHeight() / 2);

if(b2body.getLinearVelocity().y > 2f)
b2body.setLinearVelocity(b2body.getLinearVelocity().x, 2f);

if((stateTime > 0.5f &&  !destroyed)) {
System.out.println("remove");
world.destroyBody(b2body);
destroyed = true;
stateTime=0;
}
}

• thanks a lot, but still get an error. I tried to print statetime in Update method. when I fired fireball once, after 0.5, it would be removed. However, when I launched fireball for 10 times swiftly. each of fireball does not really spend 0.5 it is like the first ball takes 0.2 and then state time mixed up with state time for second fireball. then statetime becomes 0 then count up. – DHC Sep 29 '17 at 20:36
• so, I just edited, so you can see it looks like, before 0.5f, the statetime starts again,,, – DHC Sep 29 '17 at 20:42
• I am not sure ,but I guess, I just remove statetime in my ifstatement then, maybe put some delay thing before it is destroyed .. – DHC Sep 29 '17 at 20:53