1

How can I make my player move forward and backward in my top down game.I created two buttons the moveForward button and moveBackward button.Using acceleromter I move my player left and right. My main problem is the moving forward and backward of my player every time I click the buttons.It works using key up and down but I don't know how to implement using button touch.

Here is what I've coded below

// Load the sprite sheet as a texture
    cat = new Texture(Gdx.files.internal("spriteCatsheet.png"));
    catsprite = new Sprite(cat);
    catsprite.setScale(2f);
    player = new Rectangle();
    player.x = Gdx.graphics.getWidth() - player.width - 350; 
    player.y = catPlayerY;
    player.setWidth(25);

My Buttons

    //left_control
    left_paw = new Texture(Gdx.files.internal("left_paw.png"));
    myTextureRegion = new TextureRegion(left_paw);
    myTexRegionDrawable = new TextureRegionDrawable(myTextureRegion);
    moveBackward = new ImageButton(myTexRegionDrawable); //Set the button up
    moveBackward.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("left_paw.png"))));
    //the hover
    moveBackward.getStyle().imageDown = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("left_paw_hover.png"))));
    moveBackward.setPosition(10,25);
    stage.addActor(moveBackward); //Add the button to the stage to perform rendering and take input.
    Gdx.input.setInputProcessor(stage);
    moveBackward.addListener(new InputListener(){
        @Override
        public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
            System.out.println("Left Button Pressed");
           //Move player Backward
           //player.y -= 300 * Gdx.graphics.getDeltaTime();
        }
        @Override
        public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
            System.out.print("Released");

            return true;
        }
    });
    stage.addActor(moveBackward);

    //right_control
    right_paw = new Texture(Gdx.files.internal("right_paw.png"));
    myTextureRegion = new TextureRegion(right_paw);
    myTexRegionDrawable = new TextureRegionDrawable(myTextureRegion);
    moveForward = new ImageButton(myTexRegionDrawable); //Set the button up
    moveForward.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("right_paw.png"))));
    //the hover
    moveForward.getStyle().imageDown = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("right_paw-hover.png"))));
    moveForward.setPosition(517,25);
    stage.addActor(moveForward); //Add the button to the stage to perform rendering and take input.
    Gdx.input.setInputProcessor(stage);
    moveForward.addListener(new InputListener(){
        @Override
        public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
            System.out.println("Right Button Pressed");
             //Move player Forward
             //player.y += 300 * Gdx.graphics.getDeltaTime();

        }
        @Override
        public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
            return true;
        }
    });
    stage.addActor(moveForward);

Render

    spriteBatch.draw(currentFrame,player.x, player.y);

     //On keyboard 
    if(Gdx.input.isKeyPressed(Input.Keys.DOWN))player.y -= 300 * Gdx.graphics.getDeltaTime();
    if(Gdx.input.isKeyPressed(Input.Keys.UP)) player.y += 300 * Gdx.graphics.getDeltaTime();
    if(Gdx.input.isKeyPressed(Input.Keys.LEFT)) player.x -= 300 * Gdx.graphics.getDeltaTime();
    if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)) player.x  += 300 * Gdx.graphics.getDeltaTime();

    //Mobile acceleration
    if (Gdx.input.isPeripheralAvailable(Input.Peripheral.Accelerometer)) {
        player.x -= Gdx.input.getAccelerometerX();
        player.y += Gdx.input.getAccelerometerY() /1f;
    }
    if (player.x < 0) {
        player.x = 0;
        player.x += Gdx.graphics.getDeltaTime() *20 *delta;
    }
    if (player.x > Gdx.graphics.getWidth()-player.getWidth() -150) {
        player.x = Gdx.graphics.getWidth()-player.getWidth() -150;
    }

Thank's and Advance ^_^

Abhishek Aryan
  • 19,936
  • 8
  • 46
  • 65
jaZzZ
  • 127
  • 12
  • You are not doing anything except outputing some console text when pressing the buttons. You should call a method inside the listener that moves the player. – Madmenyo May 24 '17 at 07:04
  • Hello Sir @Madmenyo I remove the method inside my listener I remove this `player.y += 300 * Gdx.graphics.getDeltaTime();` it moves forward but I think it is not the proper way of moving the player forward because it 's snapping. – jaZzZ May 24 '17 at 07:09
  • `getDeltaTime` is the average delta time (over I think last 100 frames). It could be less snappy with `getRawDeltaTime`. If it is really (very noticeable) snappy/choppy it must be something else. – Madmenyo May 24 '17 at 07:27
  • I already change to `getRawDeltaTime ` still got choppy/snappy.. – jaZzZ May 24 '17 at 08:19

2 Answers2

1

You can use in this way :

MotionState motionState=MotionState.NONE;

enum MotionState {

    NONE {
        @Override
        public boolean update(Rectangle player) {
           return true;
        }
    },

    UP {
        @Override
        public boolean update(Rectangle player) {
            player.y += 300 * Gdx.graphics.getDeltaTime();
            return false;
        }
    },

    DOWN{
        @Override
        public boolean update(Rectangle player) {
            player.y -= 300 * Gdx.graphics.getDeltaTime();
            return false;
        }
    },

    LEFT{
        @Override
        public boolean update(Rectangle player)  {
            player.x -= 300 * Gdx.graphics.getDeltaTime();
            return false;
        }
    },

    RIGHT{
        @Override
        public boolean update(Rectangle player) {
            player.x  += 300 * Gdx.graphics.getDeltaTime();
            return false;
        }
    };

    public abstract boolean update(Rectangle player);
}

Inside your render() method

if(Gdx.input.isKeyPressed(Input.Keys.DOWN)) motionState = MotionState.DOWN;
if(Gdx.input.isKeyPressed(Input.Keys.UP)) motionState=MotionState.UP;
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)) motionState=MotionState.LEFT;
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)) motionState=MotionState.RIGHT;

if(motionState.update(player)) motionState=MotionState.NONE;

Now inside Button's Listener method

moveBackward.addListener(new InputListener(){
    @Override
    public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
       motionState=MotionState.NONE;
    }
    @Override
    public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
         motionState=MotionState.DOWN;  // or what you want 
        return true;
    }
});

Do for moveForward button.

Abhishek Aryan
  • 19,936
  • 8
  • 46
  • 65
0

You are not doing anything except outputing some console text when pressing the buttons. You should call a method inside the listener that moves the player.

Besides that, touchdown is "just touched" and touch up is "released". Not the other way around. In your case you want to have "button hold" functionality so you need to set a flag for each button that gets activated when touchDown/just pressed and deactivated when touchUp/released. When the flag is active this means the button is being held down. Then in your update loop you check if button/flag X is held down and do your magic.

Madmenyo
  • 8,389
  • 7
  • 52
  • 99