Menu - GameDevWeek/CodeBase GitHub Wiki

LibGDX already supports UI/Menu, but since its layouting can be a bit confusing for newcomers, we've come up with some helper classes to make things a bit easier.

Fixed Menu size

With LibGDX you usually chose a fluid menu, which adapts to your screen resolution using layouts.

We will instead chose a fixed size for our menu. Let's say our ideal menu size is 800x600. The MenuManager class will make sure, that the menu is always drawn in the center of the screen. If your resolution is smaller than 800x600, the menu will be squeezed (keeping the same aspect ratio). It's not a perfect solution, but works good enough and it enabled you to create menus quickly.

Now that we know, that all of our positions will allways be inside these dimensions, we can freely position our widgets (buttons, editboxes, checkboxes, ...) in the menu.

Pages

The MenuManager class allows you to push and pop pages. Only one page is visible at the same time. Take a look at this simple example.

The classes contained in this example:

  • MenuPage is the baseclass, from which every other page extends.
  • MenuPageRoot is the root of your menu, from which you can reach the other pages.
  • MenuPageCredits is a a page containing credits.

Let's take a look at a couple of code snippets found in the MenuPage class:

public class MenuPage extends Group { // A page must always extend com.badlogic.gdx.scenes.scene2d.Group!
//...
    public MenuPage(Skin skin, String background) { // Skin is a way to style your widgets, I'll explain later.
        super();
        this.skin = skin;

        // This adds an image to the page. In this case, a background image.
        addActor(new DecoImage(assetManager.getTexture(background)));

        // All pages must be set to invisible at start. They will be set visible by MenuManager automatically.
        setVisible(false);
    }

    @Override
    public void act(float delta) {
        // This is the "update" method. No need to act if it's invisible.
        if (isVisible()) {
            super.act(delta);
        }
    }

    @Override
    protected void drawChildren(Batch batch, float parentAlpha) {
        // This just makes sure, nothing is drawn outside of the page
        if (clipBegin(0, 0, getWidth(), getHeight())) {
            super.drawChildren(batch, parentAlpha);
            clipEnd();
        }
    }

    // This method and the following are helpers you can use to create widgets
    protected final void addLeftAlignedButton(int x, int y, int width, int height, String text, Runnable runnable) {
        TextButton button = addButton(x, y, width, height, text, runnable, "default");
        button.getLabel().setAlignment(Align.left);
    }
//...

Skin

A skin is a way to tell LibGDX how to draw widgets. You'll need to pass it to a couple of constructors. Check out the official wiki.

Widgets

Widgets are elements of the menu which LibGDX provides.

There are 2 more Widgets which are provided by us:

  • DecoImage, which is used to easily display (and change) a texture on the page.
  • RotatingDecoImage, which extends DecoImage and adds a rotation. This was used to create rotating gears as decoration in a Menu.

These widgets can also make use of mouse events.

MenuManager

So how do you use the MenuManager? It's best to take a look at the example.

// Parameters: int width, int height, Runnable onEmptyPop
private final MenuManager menuManager = new MenuManager(Main.WINDOW_WIDTH, Main.WINDOW_HEIGHT, null);

onEmptyPop will be called, when the user tried to pop a page, but none was available to pop (if you are on the root page and try to pop it). This can be used to show the game in case of an ingame menu (see this example)

Further explanations will follow. For now you'll have to figure out the rest as you go.

Further examples

Obviously, the above is just a short crash-course. If you need more examples, please take a look at these: