[Solved] How to properly remove appstates?

Hi all,

This is a simplified version of my current code. Please excuse errors in not adding everything here that I added in the previous posts (such as the ambient light before I added it in before posting). Please tell me what I’m doing wrong.

public class GameAppState extends BaseAppState implements ActionListener {

    private SimpleApplication app;
    private Node              rootNode;
    private AssetManager      assetManager;
    private AppStateManager   stateManager;
    private InputManager      inputManager;
    private ViewPort          viewPort;
    private ViewPort guiViewPort;

    //All static fields are constant throughout the game and should not be changed just for one level
    private static BulletAppState physics;
    //Not an appstate
    private static CustomSoundHandler sound;

    public static Nifty pauseGUI;
    public static NiftyJmeDisplay niftyDisplay;

    private static boolean staticInitialized = false;

    private static DirectionalLightShadowRenderer shadows;
    private static FilterPostProcessor fpp;

    public List<String> localMappings;
    public Node localRoot;

    private void initializeStatic(){
        if(staticInitialized) return;
        staticInitialized = true;

        physics = new BulletAppState();
        sound = new CustomSoundHandler();

        niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
                assetManager,
                inputManager,
                app.getAudioRenderer(),
                app.getGuiViewPort());

        //initialize pauseGUI

        //Setup scene and lighting and add to localroot
        /** A white, directional light source */ 
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());
        sun.setColor(ColorRGBA.White);
        localRoot.addLight(sun); 

        /** A white ambient light source. */ 
        AmbientLight ambient = new AmbientLight();
        ambient.setColor(ColorRGBA.White);
        rootNode.addLight(ambient); 

        //Setup bulletphysics

        localMappings = new ArrayList<>();

        //Setup input with localMappings to save the mappings into

        shadows = new DirectionalLightShadowRenderer(assetManager, 2048, 4);
        shadows.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON);
        shadows.setShadowIntensity(0.8f);
        shadows.setLight(sun);
        viewPort.addProcessor(shadows);

        fpp = new FilterPostProcessor(assetManager);
        FXAAFilter fxaa = new FXAAFilter();
        fpp.addFilter(fxaa);
    }

    @Override
    protected void initialize(Application app) {
        this.app = (SimpleApplication) app; // can cast Application to something more specific
        this.rootNode     = this.app.getRootNode();
        this.assetManager = this.app.getAssetManager();
        this.stateManager = this.app.getStateManager();
        this.inputManager = this.app.getInputManager();
        this.viewPort     = this.app.getViewPort();
        this.guiViewPort = this.app.getGuiViewPort();

        localRoot = new Node();

        initializeStatic();

        onEnable();
    }

    @Override
    protected void cleanup(Application app) {
        onDisable();
        stateManager.detach(physics);

        for(String mapping: localMappings){
            inputManager.deleteMapping(mapping);
        }

        inputManager.removeListener(this);
    }

    @Override
    protected void onEnable() {
        //Add bullet rigidbodies and such
        physics.setEnabled(true);
        rootNode.attachChild(localRoot);
        sound.enable();
        this.guiViewPort.addProcessor(niftyDisplay);
    }

    @Override
    protected void onDisable() {
        //Remove bullet rigidbodies and such
        this.guiViewPort.removeProcessor(niftyDisplay);
        physics.setEnabled(false);
        rootNode.detachChild(localRoot);
        sound.disable();
    }

    @Override
    public void onAction(String name, boolean isPressed, float tpf) {
        //Handle input
    }
}

P.S. In the tutorial, the field declarations should be in the class not in the imports section

Do not call onEnable() yourself.

99.99999999999999999999999% of the methods on AppState are NOT MEANT TO BE CALLED BY YOU!!!

These methods are called for you… you are only supposed to implement them to do stuff.

As it is, your onEnable() will be called twice… in this case it’s probably harmless but it’s still really silly.

initializeStatic() is also not a good idea.

So much of what you do seems really weird. Just create app states. Attach them. You don’t need all of that other weird garbage.

2 Likes