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
}
});
我正在尝试为我的 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
}
});