Program structure

I use AppStates for lots of things. I rarely ever use controls.

I have an app state for running background threads. I have an app state for moving the camera (or anything, really). I have an app state for a debug HUD. Lots and lots of reusable app states that I just chunk into my application whenever I need them.

A very typical super() constructor for my apps looks like this… actually, I’ll include the whole boiler play for what my main application class almost always looks like:

public class Main extends SimpleApplication {

    static Logger log = LoggerFactory.getLogger(Main.class);

    public static void main( String... args ) throws Exception {

        Main main = new Main();
        AppSettings settings = new AppSettings(true);

        // Set some defaults that will get overwritten if
        // there were previously saved settings from the last time the user
        // ran.
        settings.setWidth(1280);
        settings.setHeight(720);
        settings.setVSync(true);

        String title = "MyApp";
        settings.load(title);
        settings.setTitle(title);

        settings.setUseJoysticks(true);

        main.setSettings(settings);

        main.start();
    }

    public Main() {
        super(new StatsAppState(), new DebugKeysAppState(), new BasicProfilerState(false),
              new DebugHudState(),
              new MemoryDebugState(),
              new OptionPanelState(), // from Lemur
              new MessageState(),
              new CommandConsoleState(),
              new MainMenuState(),
              new ScreenshotAppState("", System.currentTimeMillis()));
    }

    public void simpleInitApp() {

        setPauseOnLostFocus(false);
        setDisplayFps(false);
        setDisplayStatView(false);

        GuiGlobals.initialize(this);

        GuiGlobals globals = GuiGlobals.getInstance();

        MainGameFunctions.initializeDefaultMappings(globals.getInputMapper());

        BaseStyles.loadGlassStyle();
        globals.getStyles().setDefaultStyle("glass");
        globals.setCursorEventsEnabled(false);
    }
}

For applications that don’t have a main menu, I’d add a MovementState, SkyState, LightingState, etc… But in this particular application those are children of the CompositeAppState that’s run when the game starts.

Edit: and here is the GameSessionState that is attached when the game starts for that particular application:

public class GameSessionState extends CompositeAppState {

    static Logger log = LoggerFactory.getLogger(GameSessionState.class);

    private boolean hostIsLocal = false;

    public GameSessionState() {
        super(new CameraMovementState(),
              new CameraState(),
              new LightingState(),
              new SkyState(true),
              new PostProcessingState(),
              new SkySettingsState(),
              new BuilderState(4, 4),
              new WorldViewState(),
              new ModelViewState()
              );

        addChild(new HelpState(), true);
        addChild(new SettingsState(), true);
        addChild(new ChatState(), true);
        addChild(new ToolState(), true);
    }
    
    @Override
    protected void initialize( Application app ) {
        getState(CameraState.class).setFieldOfView(60);
    }
    
    @Override
    protected void cleanup( Application app ) {
    }
    
    @Override
    protected void onEnable() {
    }
    
    @Override
    protected void onDisable() {
    }
}
6 Likes