Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LibGDX How to implement scene 2D menu tabs?

I have made an alpha version of my rpg and now I want to implement a menu with multiple tabs. When you are in game and press tab or escape I want to show a user interface that will have a bar top with 3 buttons like main menu, skill tree and inventory. The problem is that when you switch tab I need to stop drawing the previously selected tab and disable the actors from it so when you click something from the current tab it doesn't also click a button on a tab that isn't being drawn but it is there... How can I disable actors, buttons so I can draw a new tab without worrying about overlapping the current tab with the previous one?

EDIT: I want to avoid making multiple stages. I would like to have a single stage on which every tab is defined.

like image 366
Andrew Avatar asked Jun 08 '14 21:06

Andrew


1 Answers

Invisible actors don't receive touch events, making the easiest way to accomplish a tabbed interface simply setting the visibility of the tab content actors appropriately.

Here's how I would implement a tabbed interface in libgdx:

package com.badlogic.gdx.tests.lwjgl;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.ButtonGroup;
import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Stack;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.viewport.ScreenViewport;

class Game3 extends ApplicationAdapter {

    Skin skin;
    Stage stage;

    @Override
    public void create () {
        skin = new Skin(Gdx.files.internal("data/uiskin.json"));
        stage = new Stage(new ScreenViewport());

        Table main = new Table();
        main.setFillParent(true);

        // Create the tab buttons
        HorizontalGroup group = new HorizontalGroup();      
        final Button tab1 = new TextButton("Tab1", skin, "toggle");
        final Button tab2 = new TextButton("Tab2", skin, "toggle");
        final Button tab3 = new TextButton("Tab3", skin, "toggle");
        group.addActor(tab1);
        group.addActor(tab2);
        group.addActor(tab3);
        main.add(group);
        main.row();

        // Create the tab content. Just using images here for simplicity.
        Stack content = new Stack();
        final Image content1 = new Image(skin.newDrawable("white", 1,0,0,1)); 
        final Image content2 = new Image(skin.newDrawable("white", 0,1,0,1));
        final Image content3 = new Image(skin.newDrawable("white", 0,0,1,1));   
        content.addActor(content1);
        content.addActor(content2);
        content.addActor(content3);

        main.add(content).expand().fill();

        // Listen to changes in the tab button checked states
        // Set visibility of the tab content to match the checked state
        ChangeListener tab_listener = new ChangeListener(){
            @Override
            public void changed (ChangeEvent event, Actor actor) {
                content1.setVisible(tab1.isChecked());
                content2.setVisible(tab2.isChecked());
                content3.setVisible(tab3.isChecked());
            }
        };
        tab1.addListener(tab_listener);
        tab2.addListener(tab_listener);
        tab3.addListener(tab_listener);

        // Let only one tab button be checked at a time
        ButtonGroup tabs = new ButtonGroup();
        tabs.setMinCheckCount(1);
        tabs.setMaxCheckCount(1);
        tabs.add(tab1);
        tabs.add(tab2);
        tabs.add(tab3);

        stage.addActor(main);       
        Gdx.input.setInputProcessor(stage);
    }

    @Override
    public void render () {
        stage.act();
        stage.draw();
    }

    @Override
    public void dispose () {
        stage.dispose();
        skin.dispose();
    }

    public static void main (String[] args) {
        new LwjglApplication(new Game3(), new LwjglApplicationConfiguration());
    }
}
like image 59
nEx.Software Avatar answered Sep 26 '22 21:09

nEx.Software