Shooting as the game harpoon pang or super pang in libgdx

I would like to make a continuous shot just like it is done in the pang or super pang game, right now I can emulate a simple shot as if they were pistol bullets but I can't think of how to make a continuous shot from where I touch the screen until it is destroyed with the ceiling or against some object.

I am using Scene2Dand Box2Dand this is my class Actor shooting.

public class ActorDisparo extends Actor {

   private TextureRegion textureDisparo = new TextureRegion();
   private World world;
   public static Body body;
   private FixtureDef fdef;
   private String userData;
   private float anchoDisparo, altoDisparo;
   private float positionX,positionY;
   private static float porcentajeDeancho = 0,anchoMediano = 0, anchoPequeno = 0, anchoDiminuto = 0;
   private TextureRe arponRegion = new Texture();

   public ActorDisparo(World world, Texture disparo, Vector2 position, float anchoDisparo, float altoDisparo, float fuerzaX, float fuerzaY, String userData){
       this.textureDisparo = disparo;
       this.world = world;
       this.anchoDisparo = anchoDisparo;
       this.altoDisparo = altoDisparo;
       this.userData = userData;

       BodyDef bodyDef = new BodyDef();
       bodyDef.position.set(position);
       bodyDef.type = BodyDef.BodyType.DynamicBody;
       body = world.createBody(bodyDef);

       PolygonShape shapeDisparo = new PolygonShape();
       shapeDisparo.setAsBox((anchoDisparo/2)/2,altoDisparo/2);

       fdef = new FixtureDef();
       fdef.shape = shapeDisparo;
       //fdef.restitution = 0.70f;

       fdef.filter.categoryBits = BolasGame.DISPARO_BIT;
       fdef.filter.maskBits = BolasGame.BOLAROJA_BIT |
                       BolasGame.TECHO_BIT;

       body.createFixture(fdef).setUserData(userData);
       shapeDisparo.dispose();
       body.setGravityScale(0f);
       body.applyLinearImpulse(fuerzaX,fuerzaY,position.x,position.y,true);

       setSize( anchoDisparo *BolasGame.MetrosAPixels  ,altoDisparo*BolasGame.MetrosAPixels);

       //setBounds(0, 0, getWidth(), getHeight());
   }
   public float getPositionX() {
       return getPositionX();
   }

   public float getPositionY() {
       return getPositionY();
   }

   @Override
   public void act(float delta) {
      super.act(delta);
   }

   @Override
   public void draw(Batch batch, float parentAlpha) {
      super.draw(batch, parentAlpha);
      setPosition( (body.getPosition().x * BolasGame.MetrosAPixels) -     getWidth()/2, (body.getPosition().y * BolasGame.MetrosAPixels) - getHeight()/2);
      batch.draw(textureDisparo,getX(),getY(),getWidth(),getHeight());
   }

   public void detach(){
      world.destroyBody(body);
      remove();
   }

}

And this is the call I make to the actor class shoot.

if(Gdx.input.justTouched() && hasdisparado == false){
    hasdisparado =true;
    touch = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);

    stage.getCamera().unproject(touch);

    actorDisparo = new ActorDisparo(world,textureDisparo,new Vector2(touch.x/BolasGame.MetrosAPixels,touch.y/BolasGame.MetrosAPixels),20/BolasGame.MetrosAPixels,40/BolasGame.MetrosAPixels,0,2f,BolasGame.USERDATA_DISPARO);
    stage.addActor(actorDisparo);
}

The texture is an image of 446x20 representing the full harpoon.

textureDisparo = new Texture("gfx/disparo.png");

Right now I could position it in x where I touch with my finger and in y=0 and it would come out from bottom to top like a harpoon, but what I want is that the shot appears dynamically from where I do the touch with my finger and it is generated sequentially, but I do not get it, it would player and from bottom to Top taking into account the contacts with the balls and the roof or the stop you have.

 13
Author: Eslacuare, 2016-11-01

1 answers

I don't quite understand what you want, if every time the bullet object is destroyed you automatically fire again while the disapro button is pressed? or if it is a continuous shot like machine gun?

To fire again when the bullet object is destroyed you just need to change your code a little

if(Gdx.input.isTouched() && hasdisparado == false){ ///no se cual es la funcion que defina presion continua, solo utilizo "isTouched()" como ejemplo
    [...]  // <-- tu mismo codigo de la funcion
}

Then in your bullet object at the time of destroying it, you have to change the variable hasdisparado again to false. When your function update goes through again the Code section where you check the pressure, the function Gdx.input.isTouched() will remain true as long as you keep pressing the button and a new Bullet will be created.


If you want to do a continuous shot like a machine gun, you need to use a cooldown variable. When you make your first shot, set that variable to 300 (milliseconds) and since it is a video game, the game refresh or update will pass several times through that section, and each time it passes, it reduces the variable in the amount of ms that passed since the last update. When the variable reaches 0 again, you make another shot and put the value 300 back in your cooldown variable.

int shootCooldown = 0;
[...]
if(Gdx.input.isTouched()){  //no se cual es la funcion que defina presion continua, solo utilizo esto como ejemplo
    if (shootCooldown > 0)
        shootCooldown -= elapsedTime;
    if (shootCooldown <= 0){
        shootCooldown = 300;
        spawnBullet(); // <-- tu codigo para crear una bala
    }
}

Basically this would be a fragment that would help you make a continuous shooting mechanics. Additionally you would have to finish reducing the cooldown of the shot in case it is no longer pressing the button, so that it does not remain that active cooldown when you press the button again, something like:

if(!Gdx.input.isTouched() && shootCooldown > 0){
    shootCooldown -= elapsedTime;
    if (shootCooldown <= 0){
        shootCooldown = 0;
    }
}

Remember that the cooldown defines the timeout between one shot and another, not necessarily 300 is what you are looking for, maybe something faster or slower. This is one way to do it, I hope it works for you

 1
Author: Sander Rito, 2016-11-02 18:13:54