libGDX - 按钮设置为向下,即使在边界之外

libGDX - Button is set to down even if outside of bounds

我正在尝试为我的 UI 正确设置按钮点击。我希望我的按钮在单击后立即响应,而不是使用 ClickListeners touchDown 方法释放。

我创建了一个 class,它创建并显示了一个带有文本输入的 table:

public class InputBox {

    public static float OFFSET = 20;

    private Table table;

    private TextField inputField;

    private TextButton okButton;
    private TextButton closeButton;

    private String saveText;

    private TextButtonStyle style;

    private Skin skin;

    public InputBox(Skin skin, float x, float y, float width, float height, boolean visible) {

        this.skin = skin;

        table = new Table();

        // Creating a new style as suggested.
        style = new TextButtonStyle();
        style.up = skin.getDrawable("button_normal_up");
        style.down = skin.getDrawable("button_normal_down");
        style.font = skin.getFont("default");

        inputField = new TextField("", skin);

        okButton = new TextButton("Ok", style);     
        okButton.addListener(new ClickListener() {

            @Override
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {

                if (button != Buttons.LEFT) {

                    return false;
                }
                Game.resources.getSound("click_2").play();
                table.setVisible(false);

                if (inputField.getText().equals("")) {

                    saveText = null;
                    return false;
                }

                saveText = inputField.getText();                                
                return true;
            }

        });

        closeButton = new TextButton("Close", style);
        closeButton.addListener(new ClickListener() {           

            @Override
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {

                if (button != Buttons.LEFT) {

                    return false;
                }
                Game.resources.getSound("click_2").play();

                saveText = null;                

                table.setVisible(false);                

                return true;
            }       
        });

        table.setVisible(visible);

        table.setX(x);
        table.setY(y);

        table.setWidth(width);
        table.setHeight(height);

        table.add(inputField).colspan(2).center().width(width - OFFSET).expand().padRight(2);
        table.row();
        table.add(okButton).width(width / 2 - OFFSET / 2).right();
        table.add(closeButton).width(width / 2 - OFFSET / 2).left();
        table.pad(5);
    }

    public void setUnclicked() {


        style.down = skin.getDrawable("button_normal_up"); 

        // I think these two lines ar uneeded.
        okButton.setStyle(style);
        closeButton.setStyle(style);
    }

    public void setClicked() {

        style.down = skin.getDrawable("button_normal_down");

        // Same here.
        okButton.setStyle(style);
        closeButton.setStyle(style);
    }

    public void setText(String text) {

        inputField.setText(text);
    }

    public String getSaveTextOnce() {

        String temp = saveText;

        saveText = null;

        return temp;
    }

    public void setBackground(Drawable background) {

        table.setBackground(background);
    }

    public boolean isVisible() {

        return table.isVisible();
    }

    public void setVisible(boolean visible) {

        table.setVisible(visible);
    }

    public Table getTable() { 

        return table;
    }
}

单击其他按钮后 table 被设置为可见:

// Save map button.
saveMap = new ImageButton(new ImageButtonStyle());
saveMap.getStyle().imageUp = uiSkin.getDrawable("save");
saveMap.getStyle().up = uiSkin.getDrawable("button_flat_up");
saveMap.getStyle().down = uiSkin.getDrawable("button_flat_down");

saveMap.addListener(new ClickListener() {

    public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {

        if (button != Buttons.LEFT) {

            return false;
        }

        Game.resources.getSound("click_2").play();

        if (saveBox.isVisible()) {

            saveBox.setVisible(false);  
            saveBox.setUnclicked();
            return false;
        }
        saveBox.setVisible(true);
        saveBox.setClicked();

        return true;
    }       
});

saveMap 按钮的整个 class:http://pastebin.com/62ZGfcch

但是,如果我通过单击 "ok" 或 "close" 按钮关闭 table,然后单击并按住显示 table 按钮,table 再次出现并按住上次单击的按钮。

此视频说明了正在发生的事情: https://www.youtube.com/watch?v=Jf3WzU8G4dE&feature=youtu.be

如果我在按住鼠标的同时移动鼠标,table 上最后单击的按钮将重置为正常状态。

首先,我建议您使用 TextButtonStyle 实例而不是 Skin 实例来设置按钮的样式。

您可以通过某种方式获取 TextButton 对 saveMap.addListener 匿名内部 class 的引用。然后您可以手动设置 Ok 和 Cancel TextButton 的样式,如下所示:

public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {

    Game.resources.getSound("click_2").play();

    if (saveBox.isVisible()) {

        saveBox.setVisible(false); 
        okButtonReference.setStyle(unclickedTextButtonStyle) // Not-clicked TextButtonStyle as parameter

        cancelButtonReference.setStyle(unclickedTextButtonStyle) // Not clicked TextButtonStyle as parameter.
        return false;
    }
    saveBox.setVisible(true);

    return true;
}

通过调用 setStyle() 强制 TextButton 改变它的 TextButtonStyle,您可以确信按钮会改变。

我还注意到您没有在 Table 对象上调用 debug() 方法。这不是必需的,但建议这样做:

    table.add(inputField).colspan(2).center().width(width - OFFSET).expand().padRight(2);
    table.row();
    table.add(okButton).width(width / 2 - OFFSET / 2).right();
    table.add(closeButton).width(width / 2 - OFFSET / 2).left();
    table.pad(5);
    table.debug();

经过更多尝试后,我发现我设置游戏 InputProcessor 的方式导致了这个问题。我没有正确处理touchUp事件。

Game.inputs.addProcessor(new InputProcessor() {

    ...

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {

        releasedButton = -1;

        if (UI.isOver()) {

            return false;
        }
        if (button == Buttons.LEFT) {

            releasedButton = Buttons.LEFT;
        }
        if (button == Buttons.RIGHT) {

            releasedButton = Buttons.RIGHT;
        }       
        return true; // <--- setting this to false fixes the issue
    }           
});