I use LibGDX buttons for touch input (previously used desktop mode and keyboard keys. Until now, button listeners work as intended, but I can’t position these buttons the way I want. I tried to look through the documentation and some examples, and I don’t I can understand the problem here, but from what I read there were a few key things that I noticed:
- Buttons
- should be placed in a table
- tables can (and should) be nested
- only the main table should populate the parent element.
What I want to do is to have shortcuts (tableLabs) packed at the top (according to the original Mario), and buttons that will be aligned in the lower corners (so that the button on the left will be in the lower left corner and the button on the right lower right) with the navigation buttons directly above the direction buttons without considering the screen size, something similar to the design of the Java Swing frame.
Finally, I use simple "->", "<-" and "^" as placeholders for future button graphics.
So far, the result is as follows:

public class Hud implements Disposable{
public Stage stage;
public Viewport viewport;
private Integer worldTimer;
private float timeCount;
private static Integer score;
Label countDownLabel;
static Label scoreLabel;
Label timeLabel;
Label levelLabel;
Label worldLabel;
Label marioLabel;
TextButton butL, butR, butJ;
public Hud(SpriteBatch spriteBatch){
worldTimer = 300;
timeCount = 0;
score = 0;
viewport = new FitViewport(SuperMario.WORLDWIDTH, SuperMario.WORLDHEIGHT, new OrthographicCamera());
stage = new Stage(viewport, spriteBatch);
Table mainTable = new Table();
mainTable.setFillParent(true);
Table tableLabs = new Table();
tableLabs.top();
countDownLabel = new Label(String.format("%03d", worldTimer), new Label.LabelStyle(new BitmapFont(), Color.WHITE));
scoreLabel = new Label(String.format("%06d", score), new Label.LabelStyle(new BitmapFont(), Color.WHITE));
timeLabel = new Label("TIME", new Label.LabelStyle(new BitmapFont(), Color.WHITE));
levelLabel = new Label("1-1", new Label.LabelStyle(new BitmapFont(), Color.WHITE));
worldLabel = new Label("WORLD", new Label.LabelStyle(new BitmapFont(), Color.WHITE));
marioLabel = new Label("MARIO", new Label.LabelStyle(new BitmapFont(), Color.WHITE));
tableLabs.add(marioLabel).expandX().padTop(10);
tableLabs.add(worldLabel).expandX().padTop(10);
tableLabs.add(timeLabel).expandX().padTop(10);
tableLabs.row();
tableLabs.add(scoreLabel).expandX().padTop(10);
tableLabs.add(levelLabel).expandX().padTop(10);
tableLabs.add(countDownLabel).expandX().padTop(10);
Table butTable = new Table();
butTable.bottom();
TextButton.TextButtonStyle tbs = new TextButton.TextButtonStyle();
tbs.font = new BitmapFont();
butR = new TextButton("b1", tbs);
butR.setText("->");
butR.setColor(Color.FIREBRICK);
butR.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
Gdx.app.log("B-right", "pressed");
}
});
butL = new TextButton("b2", tbs);
butL.setText("<-");
butL.setColor(Color.FIREBRICK);
butL.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
Gdx.app.log("B-left", "pressed");
}
});
butJ = new TextButton("b3", tbs);
butJ.setText("^");
butJ.setColor(Color.FIREBRICK);
butJ.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
Gdx.app.log("B-jump", "pressed");
}
});
butTable.setDebug(true);
butTable.add(butJ).expandX().padBottom(10).left().expand().padRight(10);
butTable.add(butJ).expandX().padBottom(10).right().expand().padLeft(10);
butTable.row();
butTable.add(butL).expandX().padBottom(10).left().expand().padRight(10);
butTable.add(butR).expandX().padBottom(10).right().expand().padLeft(10);
mainTable.add(tableLabs).expand();
mainTable.row();
mainTable.add(butTable).expand();
mainTable.setDebug(true);
stage.addActor(mainTable);
Gdx.input.setInputProcessor(stage);
}
public void update(float dt){
timeCount+= dt;
if(timeCount >=1){
worldTimer--;
countDownLabel.setText(String.format("%03d", worldTimer));
timeCount--;
}
}
public static void addScore(int value){
score += value;
scoreLabel.setText(String.format("%06d", score));
}
@Override
public void dispose() {
stage.dispose();
}
}