Using scene2d.ui with libgdx: where does the skin come from?

Don Kirkby picture Don Kirkby · Aug 30, 2013 · Viewed 8.5k times · Source

I've read about libgdx's scene2d features, including the UI elements, but I can't get them to work. They all seem to use a skin object, how do I create one?

I've gone through the nice tutorial that creates a simple libgdx game catching raindrops in a bucket, and I've created a simple board game app by loading images with a texture atlas. However, scene2d sounds like a better way to control the moving pieces in a board game app, as well as any buttons and menus.

Answer

Don Kirkby picture Don Kirkby · Aug 30, 2013

To load a skin, you can start with the sample skin files used in the libgdx test project.

  1. Atlaspack File
  2. Json File
  3. Atlaspack Image
  4. Font File

There's a bit more detail in this question, and I found that I had to move the files into a subdirectory of assets to avoid a bug in the HTML version. (If I leave files in the assets folder, I see an error message like, "GwtApplication: exception: Error reading file data/uiskin.json.")

I posted a complete example that displays a single button, and the interesting code is all in the game class. The example is so simple that you only need two member variables to hold the scene and the button.

private Stage stage;
private TextButton button;

To create the skin, you just load the data file.

Skin skin = new Skin(Gdx.files.internal("data/uiskin.json"));

Wire the button into the stage.

stage = new Stage();
button = new TextButton("Click Me!", skin);
stage.addActor(button);

Wire a listener into the button, and register the stage to receive events.

button.addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        button.setText("Clicked!");
    }
});
Gdx.input.setInputProcessor(stage);

The render() method is basically a call to stage.draw().

Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
stage.draw();

Then you just need to layout the screen when it resizes.

button.setPosition(
        (width-button.getWidth())/2, 
        (height-button.getHeight())/2);

If your screen is more complicated, consider using a Table.

If you want to use a different font, you can generate the font file and image file using Hiero. After you've done that, you'll have to take the new font image and use the TexturePacker to repack it with the other skin assets.