1
\$\begingroup\$

In my game(2D game) I have these fireball objects. When I launch a fireball I want to destroy the object (because I'm not going to use it anymore). I tried deleting the fireballs, but, from what I can see, I'm just deleting the images, not the whole object. Now, this doesn't have a huge impact on performance when the fireballs are just a few, but my game becomes pretty slow if the object count increases.

For an example, when I fire three fireballs, the third one is the only one that disappeares, while the first and second one are still alive, just without any image.

I hope someone can help me out.

Weapon.java

public abstract class Weapon extends Sprite {

public PlayScreen screen;
public static World world;
public float stateTime;
public boolean rightside;
public boolean setToDestroy;
public boolean destroyed;


protected  Body body;

public  Weapon(PlayScreen screen, float x, float y, boolean rightside){
    this.screen = screen;
    this.world = screen.getWorld();
    this.rightside = rightside;
    setBounds(x, y, 6 / Advanture.PPM, 6 / Advanture.PPM);
    defineWeapon();
    stateTime = 0;
}

public void draw(Batch batch){
if(!destroyed)
    super.draw(batch);
}

public void update(Float dt){
    if(setToDestroy&&!destroyed){
        destroyed = true;
        world.destroyBody(body);

    }
}
protected abstract void defineWeapon();

public void setToDestroy(){
    setToDestroy = true;
}
public boolean isDestroyed(){
    return destroyed;
}

}

FireBall.java

public class FireBall extends Weapon {

private static TextureRegion tex;
private float rotate;
public boolean remove = false;
public static ArrayList<Body> bodies = new ArrayList<Body>();
public float destroyTimer = 3f;

public FireBall(PlayScreen screen, float x, float y, boolean rightside) {

    super(screen,x,y, rightside);


    tex = new TextureRegion(screen.getAtlas().findRegion("fireball"),0,0,40,40);
    setRegion(tex);
    defineWeapon(); 
}

public void update (float deltaTime) {
     super.update(deltaTime);        
     destroyTimer-= deltaTime;
     rotate +=100;

     rotate(rotate);
     setPosition(body.getPosition().x - getWidth() / 2, body.getPosition().y - getHeight() / 2)  ;

    if(destroyTimer <= 0){
       setToDestroy();

    }


 }

@Override
protected void defineWeapon() {

    BodyDef bdef = new BodyDef();
    bdef.position.set(rightside ? getX() + 12 / Advanture.PPM : getX() - 12 / Advanture.PPM, getY());
    bdef.type = BodyDef.BodyType.DynamicBody;


           if (!world.isLocked()) {
                body = world.createBody(bdef);
           }
   FixtureDef fdef = new FixtureDef();
   CircleShape shape = new CircleShape();
   shape.setRadius(3 / Advanture.PPM);
    fdef.filter.categoryBits = Advanture.FIREBALL_BIT;
    fdef.filter.maskBits = Advanture.GROUND_BIT
           | Advanture.Enemy_Head_BIT
           | Advanture.BRICK_BIT
           | Advanture.COIN_BIT
           | Advanture.Enemy_BIT;
   fdef.shape = shape;
   fdef.restitution = 1;
    fdef.friction = 0;
   body.setLinearVelocity(new Vector2(rightside ? 2 : -2, 2.5f));
   body.createFixture(fdef).setUserData(this); 


}
public void draw(Batch batch){
    if(!destroyed)
        super.draw(batch);
        //batch.draw(tex,x,y);
}
public void render (SpriteBatch batch) {
    batch.draw(tex,x,y);
}

 }

PlayScreen.java

   private ArrayList<FireBall> fireballs = new ArrayList<FireBall>();
    ......
   @Override
   public void render(float delta) {
  if(Gdx.input.isKeyJustPressed(Input.Keys.SPACE)){ 
  // generating fireball by pressing space key
        fireballs.add(new FireBall(this, b2body.getPosition().x, b2body.getPosition().y, Blue.runRightSide ? true : false));

    }

 ArrayList<FireBall> fireBallToRemove = new ArrayList<FireBall>();
    for (FireBall ball : fireballs) {
        ball.update(delta);
        if (ball.remove)
            fireBallToRemove.add(ball);
    }
}
fireballs.removeAll(fireBallToRemove);

   game.batch.begin();
    ArrayList<FireBall> FireballToRemove2 = new ArrayList<FireBall>();
    for (FireBall ball : fireballs) {
        // System.out.println(PlayScreen.touchController.getDeltaX()+"###");
        if(ball.isDestroyed()){
            FireballToRemove2.add(ball);
        }

        ball.draw(game.batch);
    }
    FireballToRemove2.removeAll(itemToRemove2);
    game.batch.end();
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

It's not enough to remove the fire balls from your fireBalls collection, you also have to destroy the Box2D Body.

Try adding a destroyBody call when cleaning up destroyed bodies.

   if (ball.remove) {
        fireBallToRemove.add(ball);
        world.destroyBody(ball.body);
   }
\$\endgroup\$
7
  • \$\begingroup\$ it does not work well, it is still... \$\endgroup\$
    – DHC
    Commented Dec 15, 2017 at 12:34
  • \$\begingroup\$ it is still not to clear all the bodies... it is only working for a last body.. \$\endgroup\$
    – DHC
    Commented Dec 15, 2017 at 12:57
  • \$\begingroup\$ @DHC have you debugged it to make sure that piece of code is being hit for the balls you expect? \$\endgroup\$
    – bornander
    Commented Dec 15, 2017 at 14:28
  • \$\begingroup\$ @DHC have you debugged it to make sure that piece of code is being hit for the balls you expect? \$\endgroup\$
    – bornander
    Commented Dec 15, 2017 at 14:28
  • \$\begingroup\$ yes, I have checked this, I guess the issue is synchronizing. this is because when new ball is created, the previous one's image which looks like fire ball is disappeared then new ball is drawn as fireball image. Do you have any idea of this? \$\endgroup\$
    – DHC
    Commented Dec 15, 2017 at 15:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .