[SOLVED] Screen switching

Hello,

I have a little bug with screens switching.

Each AppState have one screen.
Screens are handled like this :
[java]
@Override
public void initialize(AppStateManager stateManager, Application app) {
this.app = (SimpleApplication) app;

    mainMenuGuiNode = new Node("Main Menu Gui Node");
    this.app.getGuiNode().attachChild(mainMenuGuiNode);

    screen = new MainMenuScreen(this.app);
    setEnabled(true);

    super.initialize(stateManager, app);
}

@Override
public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);

    if (enabled) {
        this.app.getGuiNode().attachChild(mainMenuGuiNode);
        mainMenuGuiNode.addControl(screen);
    } else {
        screen.getGUINode().removeControl(screen);
        screen.getGUINode().removeFromParent();
    }
}

[/java]

But if switch to an other AppState with an other screen, the old one is removed and the new one is added but the inputs on the ButtonAdapters (could be for others elements too) are still here.
So is there an other method to clear screens properly, it is a bug or I do it bad?

@jonesadev said: Hello,

I have a little bug with screens switching.

Each AppState have one screen.
Screens are handled like this :
[java]
@Override
public void initialize(AppStateManager stateManager, Application app) {
this.app = (SimpleApplication) app;

    mainMenuGuiNode = new Node("Main Menu Gui Node");
    this.app.getGuiNode().attachChild(mainMenuGuiNode);

    screen = new MainMenuScreen(this.app);
    setEnabled(true);

    super.initialize(stateManager, app);
}

@Override
public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);

    if (enabled) {
        this.app.getGuiNode().attachChild(mainMenuGuiNode);
        mainMenuGuiNode.addControl(screen);
    } else {
        screen.getGUINode().removeControl(screen);
        screen.getGUINode().removeFromParent();
    }
}

[/java]

But if switch to an other AppState with an other screen, the old one is removed and the new one is added but the inputs on the ButtonAdapters (could be for others elements too) are still here.
So is there an other method to clear screens properly, it is a bug or I do it bad?

Screen works differently than it does in Nifty. You only need a single screen and then you can use AppState to organize your different “screens” (or group of elements I guess you would call it).

You can use 2 different approaches for building out the screens and adding/removing the components.

  1. Create the elements on when you instantiate the AppState, add the to the screen and then hide the elements (keeping a reference to element but removing it from the guiNode). Then use initialize to call show or showWithEffect and use cleanup to hide or hideWithEffect
  2. Create the elements the same as above but add them to the screen in initialize and removeElement in cleanup.

Personally, I use option 1.

Let me dig up a for instance using an AppState:

[java]
public class Welcome extends AbstractAppState {
private Main main;
private Screen screen;
private UIButton login, cont, exit;
private Vector2f baDim = new Vector2f(),
b1InitPos = new Vector2f(),
b2InitPos = new Vector2f(),
b3InitPos = new Vector2f();
private float spacer = 30;
private Effect slideIn1, slideIn2, slideIn3,
slideOut1, slideOut2, slideOut3;

public Welcome(Main main, Screen screen) {
	this.main = main;
	this.screen = screen;
	spacer *= main.getGameScale();
	
	initScreen();
}

private void initScreen() {
	baDim.set(screen.getWidth()/2, main.getButtonHeight());
	
	b1InitPos.set(screen.getWidth()/2-(baDim.x/2), screen.getHeight()/2+(baDim.y/2)+spacer);
	b2InitPos.set(screen.getWidth()/2-(baDim.x/2), screen.getHeight()/2-(baDim.y/2));
	b3InitPos.set(screen.getWidth()/2-(baDim.x/2), screen.getHeight()/2-(baDim.y/2)-(baDim.y)-spacer);
	
	login = new UIButton(main, screen, "login", "Login", Vector2f.ZERO, baDim) {
		@Override
		public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
			super.onButtonMouseLeftUp(evt, toggled);
			main.loadGameState(GameState.Login);
		}
	};
	slideIn1 = main.getBounceEffect(login, EffectType.SlideIn, EffectEvent.Show, EffectDirection.Top);
	slideOut1 = main.getBounceEffect(login, EffectType.SlideOut, EffectEvent.Hide, EffectDirection.Left);
	login.addEffect(EffectEvent.Show, slideIn1);
	login.addEffect(EffectEvent.Hide, slideOut1);
	
	cont = new UIButton(main, screen, "cont", "Continue", Vector2f.ZERO, baDim) {
		@Override
		public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
			super.onButtonMouseLeftUp(evt, toggled);
			main.loadGameState(GameState.Select);
		}
	};
	slideIn2 = main.getBounceEffect(cont, EffectType.SlideIn, EffectEvent.Show, EffectDirection.Bottom);
	slideOut2 = main.getBounceEffect(cont, EffectType.SlideOut, EffectEvent.Hide, EffectDirection.Right);
	cont.addEffect(EffectEvent.Show, slideIn2);
	cont.addEffect(EffectEvent.Hide, slideOut2);
	
	exit = new UIButton(main, screen, "exit", "Exit", Vector2f.ZERO, baDim) {
		@Override
		public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
			super.onButtonMouseLeftUp(evt, toggled);
			main.stop();
		}
	};
	slideIn3 = main.getBounceEffect(exit, EffectType.SlideIn, EffectEvent.Show, EffectDirection.Bottom);
	slideOut3 = main.getBounceEffect(exit, EffectType.SlideOut, EffectEvent.Hide, EffectDirection.Left);
	exit.addEffect(EffectEvent.Show, slideIn3);
	exit.addEffect(EffectEvent.Hide, slideOut3);
	
	screen.addElement(login, true);
	login.setPosition(b1InitPos);
	screen.addElement(cont, true);
	cont.setPosition(b2InitPos);
	screen.addElement(exit, true);
	exit.setPosition(b3InitPos);
}

@Override
public void initialize(AppStateManager stateManager, Application app) {
	login.showWithEffect();
	cont.showWithEffect();
	exit.showWithEffect();
}

@Override
public void update(float tpf) {
	
}

@Override
public void cleanup() {
	login.hideWithEffect();
	cont.hideWithEffect();
	exit.hideWithEffect();
}

}

[/java]

And just for the sake of knowing the getBounceEffect is…

[java]
public Effect getBounceEffect(Element el, Effect.EffectType type, Effect.EffectEvent event, Effect.EffectDirection dir) {
Effect fx = new Effect(type, event, 0.5f);
fx.setInterpolation(Interpolation.bounceOut);
fx.setEffectDirection(dir);
fx.setElement(el);
return fx;
}
[/java]

I guess I should mention… UIButton is basically a button that uses TextElement like I showed in the other example

EDIT: I should also mention, the only reason I call super.onButtonMouseLeftDown()/Up() is I have sounds set up in LeftDown, LeftUp of UIButton. There is no really need to do this otherwise, as they are abstract methods in Button and ButtonAdapter.

Thank you, I got it.

1 Like