Why doesn't my approach work to continuously repeat an action till a libgdx scene2d button is pressed and stop it when the button is released?

不打扰是莪最后的温柔 提交于 2019-12-25 14:01:46

问题


I know many questions have been asked to solve similar problem but i could not find an answer to it.

Problem : I have made a screen for my libgdx game which looks like the following screenshot.

I want the input through touch only.When i press and hold the button labeled 'lower' it decrements the number in the middle once. I want it to keep decrementing until i release the 'lower' button. I have placed the button in a table, which in turn is added on a stage. To achieve what i want i used the following approach :

    TextButton less;   //for the button labeled 'lower'
    ....

***constructor start****
            stage = new Stage(new ScreenViewport());
            Gdx.input.setInputProcessor(stage);
            table = new Table();
            table.setFillParent(true);
            stage.addActor(table);
    ......
    ......
            style = new TextButton.TextButtonStyle();
            style.up = new TextureRegionDrawable(upRegion);
            style.down = new TextureRegionDrawable(downRegion);
            style.font = buttonFont;
            less = new TextButton("lower", style);
            table.add(less).expand().fill();
    ....
    ....
    less.addListener(new ChangeListener() {
     @Override
                public void changed(ChangeEvent event, Actor actor) {
                    while(less.isPressed()) {
                        Gdx.app.log("ispressed ","yes");
                        curLevel--;
                        level.setText("" + curLevel);
                        Gdx.app.log("curLevel: ",curLevel+"");
                        try{
                            Thread.sleep(1000);
                        }catch (Exception e){

                        }
                    }
                }
    }
....
....
***constructor ends****

But the while loop in changed() goes infinite even if i release the "less/lower" button. I have also tried the solution to this question but this also results in infinite loop.

Also my project details are : (if they matter) :

ext {
        appName = 'kombat'
        gdxVersion = '1.5.2'
        roboVMVersion = '1.0.0-beta-01'
        box2DLightsVersion = '1.3'
        ashleyVersion = '1.3.1'
        aiVersion = '1.4.0'
    }

I tried solution from gaRos but as a result the number in the label goes on decreasing infinitely even after a single touch and release. Here is what i did to follow gaRos's instructions :

  1. Overrode the act method

            package com.zeher.kombat;
            import com.badlogic.gdx.scenes.scene2d.ui.Skin;
            import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
            import com.zeher.kombat.Screens.LevelChooser;
            /**
               * Created by zucky on 10/4/2015.
            */
                public class LessButton extends TextButton {
                    LevelChooser lc;
                    public LessButton(String text,TextButton.TextButtonStyle skin,Kombat game) {
        super(text, skin);
        this.lc=game.introScreen.lc;
    
    }
    @Override
    public void act(float delta){
        if(lc.lowerFlag ) {
            lc.curLevel--;
            lc.level.setText("" + lc.curLevel);
        }
    
    }
    

    }

  2. Used the inputListener.

             less.addListener(new InputListener() {
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            lowerFlag = true;
                return false;
            }
            public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
                lowerFlag = false;
                Gdx.app.log("occured: ","touchUp on less");
            }
        });
    

But the problem is that the touchUp event does not get fired and lowerFlag never switches to false.

Kindly tell me what is causing this unexpected behaviour and how to handle the press and hold gesture the way i want.


回答1:


TextButton is an Actor, so you can set an InputListener for it.

That interface has two methods to implement:

less.addListener(new InputListener() {
        public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
                lowerFlag = true;
                return true;
        }


    public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
            lowerFlag = false;
        }
 }); 

And you override the act method of the button and lower the value if the flag is true. Use the delta as a parameter how fast you want to decrease curLevel.

(if the delta is bigger decrease more, if is lower decrease less)




回答2:


First of all, i want to thank gaRos for giving a hint.

  1. The listener we should be using with actors for this purpose is ActorGestureListener . It should be like this :

    less.addListener(new ActorGestureListener() {
            public void touchDown(InputEvent event, float x, float y, int pointer, int button) {
                lowerFlag = true;
                Gdx.app.log("occured: ","touchDown on less"); //to test whether it works or not
            }
    
    
            public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
                lowerFlag = false;
                Gdx.app.log("occured: ","touchUp on less");
            }
    });
    
  2. Now override the act method for that 'less' button by making a new class which extends TextButton such that it lowers the value if the flag is true. Use the delta as a parameter how fast you want to decrease curLevel.

(if the delta is bigger decrease more, if is lower decrease less). For example i created the class LessButton.java.

    public class LessButton extends TextButton {
    LevelChooser lc;
    public LessButton(String text, TextButton.TextButtonStyle skin,Kombat game) {
        super(text, skin);
        this.lc=game.introScreen.lc;
    }
    @Override
    public void act(float delta){
        wait+=delta;
        if(lc.lowerFlag && lc.curLevel>0 && wait>delta*8) {
            lc.curLevel--;
            lc.level.setText("" + lc.curLevel);
            wait=0f;
        }
    }
    }

3. Now use it like this:

        LessButton less;
        ....
        less = new LessButton("lower", style,game);


来源:https://stackoverflow.com/questions/32818163/why-doesnt-my-approach-work-to-continuously-repeat-an-action-till-a-libgdx-scen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!