0
votes

I'm making a simple point&click game using libGdx and their Scene2d. Now, when I enter a location my Stage is cleared and new Actors are beeing attached. It doesnt feel right and its not efficient.

Can I make all Actors at the begining (except backgrounds, I will load them when entering a location), add them to Stage and associate them with locations, so the Stage would know witch to draw?

My only idea was to check that in draw and act methods of every actor, but that would mean houndreds of checks in a loop. Maybe Scene2d got something to help me out? Or maybe there is another way to do it?

1

1 Answers

0
votes

My only idea was to check that in draw and act methods of every actor, but that would mean houndreds of checks in a loop.

Yes, that will be inneficient, and above all, a hell to maintain.

Now, when I enter a location my Stage is cleared and new Actors are beeing attached.

This is where your problem is, you're not using scene2D as it should be IMHO. I hope you're up for an intense architecture & code refactoring session.

When entering a new location, you should be entering a new stage. So first, you should have several stages :

class MainMenu extends Stage {
    public MainMenu(){
        // Add buttons to play or quit the game
    }
}

class PointNClickStage extends Stage {
    // Add stuff common to all point'n click stages such as an inventory display
}

class Island extends PointNClickStage {
    public Island (){
        // Add some palm trees and an hidden chest
    }
}

class PirateShip extends PointNClickStage {
    public PirateShip(){
        // Add some pirates and their ship
    }
} 

... etc

Then in your application listener, you should implement a way to change the current stage being rendered. Conceptually, this is often called a "scene/stage director". Some scene-based frameworks, such as Cocos2D provides their own scene director, but libgdx doesn't currently. So, you have to implement this mechanism by yourself and here is a very basic example to help you get the gist of it :

public MyApp extends ApplicationAdapter { 

    private Stage currentStage;

    private static MyApp instance;

    // ...

    @Override
    public void create () {
        instance = this;
        MyApp.setStage(new MainMenu()); // The game begins in the main menu
    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(0.15f, 0.1f, 0.15f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        currentStage.act();
        currentStage.draw();
    }

    public static void setStage(Stage stage){
        instance.currentStage = stage;
        Gdx.input.setInputProcessor(stage); // Important ;)
    }

    // ...

}

So that to change the location (current stage) you will only have to do :

MyApp.setStage(new PirateShip())

Then, if you don't want to recreate a new stage every time you change your location, you may initialize and keep a reference on them somewhere so that you will be able to change the location like that for example.

MyApp.setStage(some_list_containing_initialized_stage.get(id))


Alternatively, you may also look into this libgdx extension that provides scene2d utils classes such as a scene director, and transitions that may be useful for you if you don't want to reinvent the wheel later.