Search code examples
libgdxbox2dtiled

Libgdx Box2D create Bodies


in my libgdx tiles 2D jump and run game I want to create Bodies every second at the positin of my cannons, but as far as I am, only one cannon shoots every second. Can anyone help me how to fix this?

Heres where I create my cannons:

//create cannon bodies/fixtures
    cannons = new Array<Cannon>();
    for (MapObject object : map.getLayers().get(5).getObjects().getByType(RectangleMapObject.class)) {
        recta = ((RectangleMapObject) object).getRectangle();
        cannons.add(new Cannon(screen, recta.getX(), recta.getY()));
    }

}

    public float X() {
        return recta.getX();
    }

    public float Y() {
        return recta.getY();
    }

Here I add canons( that works for every position) :

private Array<Bullet> bullets;

public Cannon(PlayScreen screen, float x, float y) {
    super(screen, x, y);
    setBounds(getX(), getY(), getWidth(), getHeight());
}

public Cannon() {
    super();
}

@Override
protected void defineTrap() {
    b2body = Body.addStatic(b2body, world, 0f, getX(), getY(), 32, x.CANNON_BIT, "cannon");
    createBullet();
}

public void createBullet() {
    bullets = new Array<Bullet>();
    bullets.add(new Bullet(screen, getX(), getY()));
}

Here I add the first bullet(that waoks too for all cannons):

public Bullet(PlayScreen screen, float x, float y) {
    super(screen, x, y);
    setBounds(getX(), getY(), getWidth(), getHeight());
}

public Bullet() {

}

@Override
public void defineTrap() {
    b2body = Body.addDynamic(b2body, world, 0f, getX(), getY(), 8, x.BULLET_BIT, "bullet");
    b2body.setLinearVelocity(new Vector2(-1f, 0));
    b2body.setGravityScale(0);
}

And here I want every cannon to shoot, but only one does (its my render mehtod):

if (TimeUtils.timeSinceNanos(startTime) > 1000000000) {
        bullets = new Array<Bullet>();
        bullets.add(new Bullet(this, creator.X(), creator.Y()));
        startTime = TimeUtils.nanoTime();
    }

I hope you can help me!


Solution

  • You should iterate through all cannons and call some method that can access the private field bullets, I called it addBullet(Screen, float, float). You might to need to do something with creator before addBullet() as I'm unsure what you are doing with it.

    if (TimeUtils.timeSinceNanos(startTime) > 1000000000) {
        for(int i = 0; i < Cannons.size; i++) {
            Cannon cannon = cannons.get(i);
            cannon.addBullet(this, creator.X(), creator.Y());
        }
        startTime = TimeUtils.nanoTime();
    }
    

    Then create the addBullet method in the Cannon class.

    public void addBullet(Screen screen, float x, float y) {
        bullets.add(new Bullet(screen, x, y));
    }
    

    As far as I can tell there is no reason to reinitialize the bullet array every time as you have been doing. Just use pop(); or removeIndex(index); to remove the array items that are no longer used. You could add some more methods to the Cannon class

    public void removeLastBullet() {
        bullets.pop();
    }
    
    public void removeBullet(int i) {
        bullets.removeIndex(i);
    }