LibGDX loading scene2D widgets very slow for first time, need suggestions

556 Views Asked by At

I started using scene2D in my LibGDX game to make a more professional looking login/register menu. The only problem is that switching to those menus is very long for menu navigation (3-5 sec).

I want to know if there is a better way to load them before hand, like during the game's initial loading screen. The thing is that once one of the menus is loaded, it loads very quick the second time.

I know for sure that its the create method of my screens that takes this long. Here is all that it is loading:

public void create(){
    stage = new Stage(new StretchViewport(1920, 1080));
    Gdx.input.setInputProcessor(stage);
    loginBox = new Image(Textures.Gui.BOX);
    loginBox.setSize(650, 1000);
    loginBox.setPosition(635, 40);
    stage.addActor(loginBox);
    loginLBL = new Label("Login", Archipelo.SKIN, "basic-large-font", Color.LIGHT_GRAY);
    loginLBL.setPosition(880, 955); 
    stage.addActor(loginLBL);
    selectionHighlight = new Image(Textures.Gui.SELECTION_HIGHLIGHT);
    selectionHighlight.setSize(540, 140);
    stage.addActor(selectionHighlight);
    usernameTF = new TextField("", Archipelo.SKIN);
    usernameTF.setMaxLength(24);
    usernameTF.setPosition(usernameTFx, usernameTFy);
    usernameTF.setSize(400, 60);
    stage.addActor(usernameTF);
    passwordTF = new TextField("", Archipelo.SKIN);
    passwordTF.setPasswordMode(true);
    passwordTF.setPasswordCharacter('•');
    passwordTF.setPosition(passwordTFx, passwordTFy);
    passwordTF.setSize(400, 60);
    stage.addActor(passwordTF);
    usernameLBL = new Label("Username", Archipelo.SKIN, "basic-medium-font", new Color(1, 1, 1, 0.5f));
    usernameLBL.setPosition(usernameTFx + 10, usernameTFy + 5);
    stage.addActor(usernameLBL);
    passwordLBL = new Label("Password", Archipelo.SKIN, "basic-medium-font", new Color(1, 1, 1, 0.5f));
    passwordLBL.setPosition(passwordTFx + 10, passwordTFy + 5);
    stage.addActor(passwordLBL);
    remember = new CheckBox(" Remember Login?", Archipelo.SKIN);
    remember.setPosition(rememberX, rememberY);
    remember.getCells().get(0).size(30, 30);
    stage.addActor(remember);
    errorLBL = new Label("", Archipelo.SKIN, "basic-small-font", Color.RED);
    errorLBL.setPosition(750, 650);
    errorLBL.setWrap(true);
    errorLBL.setBounds(750, 500, 400, 250);
    stage.addActor(errorLBL);
    continueLBL = new Label("Continue", Archipelo.SKIN, "basic-big-font", Color.WHITE);
    continueLBL.setPosition(875, 100);
    stage.addActor(continueLBL);
}

Also, I load the uiskin files before in the game's initial loading screen. Archipelo.SKIN is a static variable that refers to that uiskin. I also wanted to mention that my screen class is custom made and that whenever create() is called it is because a new screen instance is being created.

The thing that I don't get is why it takes so long to create the screen the first time and then every other time, it still goes through the same process except its much faster. Is there a way to make it faster the first time?

Thanks in advance. If you need more info by all means ask.

1

There are 1 best solutions below

0
On BEST ANSWER

To summarize the comments...

The OP had a convenience class for texture references, that listed the textures like this:

public class Gui {

    public static final Texture BOX = new Texture("box.png");
    public static final Texture SELECTION_HIGHLIGHT= new Texture("selectionHighlight.png");
    //...

}

Since they are declared static, they are members of the class, not an instance of a class. Static members of a class are all initialized at once, but only the first time the class or an instance of the class is accessed. This setup results in all the Gui textures getting loaded all at once at some inopportune, unplanned time.

The Texture's constructor Texture(String filename) causes a texture to be loaded from a file, which is time-consuming, so the loading of the Gui class takes a few seconds.

The solution is to not instantiate member texture variables in their declaration. Instantiate them within some method so you can decide exactly when they should be loaded.