Nifty elements do not disappear

Hi,

This question is related to Dynamically remove elements (Nifty GUI),
but I have a different setup, why the solutions there are not working for me.

Basically my game is currently composed of three screens, which are used in linear fashion…

  • an introduction
  • a menu
  • the main game

The main game screen contains two viewports (different sizes, both together span the whole canvas), where one of them is dynamically de-/attached during runtime. The other screens just rely on the default viewport, which spans the whole canvas.

Now the problem is, that on the menu screen an image is loaded, which is not disappearing, as desired.
This is visible, if on the main game screen the dynamic viewport is detached.
Its not possible for me to just nifty.exit(), since the main game screen contains an image, which serves as hud.

I also tried, using

var element = // tried image & all parent elements
nifty.removeElement(nifty.getScreen("menu"), element);

also tried the suggestions, with .markForRemoval() and calling .layoutElements() on their respective parents. Doesnt have any effect… I usually call those functins, after leaving the menu screen.
Also tried removing the whole menu screens → leads to NPEs within nifty’s update cycle

See my screens below, for visual details…

game-layout

this is the menu screen

and this the game screen, with viewport 2 detached

snippet of menu screen (xml):

 <screen id="menu" controller="de.xyz.jme3.unnamed.service.NiftyAppState">
    <layer id="menu-layer" childLayout="center">
      <panel width="1024" height="768" childLayout="center" valign="center" backgroundColor="#000f"  padding="40px,80px">
        <panel width="300" height="200" align="left" valign="top" backgroundColor="#0006" childLayout="vertical" padding="75px">
          <control name="button" label="Play!" id="playBtn" align="center" valign="center">
            <interact onClick="startGame(hud)"/>
          </control>
          <control name="button" label="Quit" id="quitBtn" align="center" valign="center">
          </control>
        </panel>
        <image filename="assets/textures/tank_3d.png" id="bgImage">
          <effect>
            <onStartScreen name="fade" length="100" startDelay="0" inherit="true">
            </onStartScreen>
            <!--<onEndScreen name="fade" length="100" startDelay="0" inherit="true">-->
            <!--</onEndScreen>-->
          </effect>
        </image>
      </panel>
    </layer>
  </screen>

So to sum it up to a question. Where and when and how am I supposed to remove effectivly elements from nifty screens, if I cant rely on just exiting nifty

  • Would I do it in methods like ScreenController::onEndScreen or the nifty callback method of a button (which would jump to next screen)
  • Would I remove Elements, before or after I jumped to the next screen ?

I think this is a valid approach.

2 Likes

I kinda found a working solution for me, but tbh I dont understand, why its working only this way

It turned out, that I had two mistakes.

In my callback method, I did the nifty functions (jumping to next screen, removing elements) in wrong order

So changing

public void startGame(String nextScreen) {
    nifty.gotoScreen(nextScreen); 
    nifty.getScreen("menu").findElementById("bgImage").markForRemoval();
    nifty.getScreen("menu").findElementById("bgImage").getParent().layoutElements();
  }

to

public void startGame(String nextScreen) {
    nifty.getScreen("menu").findElementById("bgImage").markForRemoval();
    nifty.getScreen("menu").findElementById("bgImage").getParent().layoutElements();
    nifty.gotoScreen(nextScreen); 
  }

was first fix.

The second “mistake” was, that I didnt use an onEndEffect in my xml, I can achieve only the desired behaviour, if I use this effect. And tbh, I dont understand, why this is required nor is this mentioned in the nifty gui docs, afaik.

So ended up in adjusting my xml to:

...
 <image filename="assets/textures/tank_3d.png" id="bgImage">
   <effect>
     <onStartScreen name="fade" length="100" startDelay="0" inherit="true" />
     <onEndScreen name="fade" length="100" start="#f" end ="#0" inherit="true" />
   </effect>
 </image>
...

That did the trick.

2 Likes