Nifty HUD causing fps drop

Well refreshing the information is one thing, but rebuilding everything from scratch for your use case is probably a waste of resources. You can move nifty elements or change them by hand by just accessing the elements directly and making the changes you need. There are a lot of details on how to handle this on the wiki as well as the nifty bible pdf that I believe is linked in the wiki.

1 Like

As @glh3586 says in more detail:

Refreshing once per frame, not abuse.

Re-building once per frame, abuse.

Any user interface would likely build up lots of temporary garbage this way that then needs to be GC’ed. It could be even worse than that for some libraries.

By the way, if you are ever curious, I could show you how you’d do a similar UI in Lemur including a nice property panel that auto-builds itself.

Please do, I have never worked with Lemur before but it sounds nifty :slight_smile:

1 Like

Thanks, will try that

Nifty in jME 3.1 uses a batched renderer. This allows a big performance boost in complex UIs with many elements, but it does require the developer to manually dispose any screens which are inactive, so that the unused textures can be removed from the atlas.

Cool, so what is the proper way of manually disposing a screen please?

P.S. Got any examples of 2D minimap that rotates with player direction?

I guess the removeScreen method is supposed to do that.

First step would be to go through the Getting Started page to get Lemur installed + setup and stuff:

Then for the health bar, you could do it as a custom control that you attach to your mobs as needed. This control would create a ProgressBar and attach it to the guiNode. On update it would position the ProgressBar on the 2D screen based on the 3D position of the spatial to which it is attached. (Presumably you already do something like this.)

Making the ProgressBar is easy enough:
ProgressBar progress = new ProgressBar();
guNode.attachChild(progress);
progress.setLocalTranslation(appropriateLocation);

That will create a progress bar that goes from 0 to 100. If you want a different range (say 0 to maxHP) then you can do something like:
ProgressBar progress = new ProgressBar(new DefaultRangedValueModel(0, maxHP, hp));

…then to set the current HP:
progress.setValue(hp);

For a property panel, you will have to also grab the LemurProps jar from:

…include it in your project as you did the others.

There is no full documentation on PropertyPanel but there is some javadoc here which is better than nothing:
http://jmonkeyengine-contributions.github.io/Lemur/javadoc/LemurProps/com/simsilica/lemur/props/PropertyPanel.html

Basically, assuming that you have some Java object with set/get methods for your different properties (say HP, MaxHP, yaw, pitch, whatever) then you could create a panel like:

PropertyPanel properties = new PropertyPanel(“glass”); (seems there is no style-less constructor yet… my bad)

properties.addFloatProperty(“HP”, yourObject, “HP”, 0, 100, 1);
…and so on. There are both addXXField and addXXProperty methods depending on need for your particular object.

It occurs to me that this may not fit your full use-case for ‘real’ as there is currently no way to set read-only properties and there is no generic text version either. These wouldn’t be hard to add and for debug views I think it’s still probably useful.

Firefox is about to die on me as it hasn’t been restarted in 6 hours or so… or I’d say more. Anyway, maybe it’s enough to pique your curiosity. If you look around at some of my other things like IsoSurfaceDemo then you can see screen shots of the PropertyPanel using the ‘glass’ style. Styles can be changed easily enough.

Finally got it working, I love it!

Thank you very much

Whee… glad it worked. :slight_smile:

Erm…

How do I add a picture to a container?

Where can I find this information?

Like, in what way?

You mean specifically or generally? There is the docs on the wiki that I’ve been working on: Home · jMonkeyEngine-Contributions/Lemur Wiki · GitHub

…but I don’t know if they specifically answer your question. A label with an IconComponent as its icon layer is the easiest way to add an image to a container but it depends on what you mean by “add an image to a container”. Like, as a background for the container or just as an element in the container?

Both will be needed but I am primarily focused on doing something like this:

You can see under the healthbar there are the 4 corners of a square, that is an image with alpha layer. Right under it there is a blue crosshair.

So I need an invisible container that can hold an image.

Yeah, that’s no problem at all. Use a TbtBackgroundComponent and set it as the background of the container. That way your texture will even stretch intelligently.

There is a section in the docs about it:

1 Like

Hello pspeed!

Stating to get the hang of Lemur. I must say, I already like it much more then Nifty!

I working on an editor for my game to handle adding solar systems to a galaxy, then adding planets to a solar system, and then changing planet properties and stuff

When adding a child to a container it is by default added underneath. I need things in a grid kind of like:

P.S. how can I make containers draggable?

Thanks.

By default most containers have SpringGridLayout as their layout. This is a grid but by default new components create a new ‘row’ along the major axis. However, because you can pass generic constraints along then you can control this by passing rows and columns.

For the sake of this discussion, when I say ‘row’ I mean a new ‘line’ in the major axis and when I say ‘column’ I mean a new line in the minor axis. This is important because you can setup a SpringGridLayout to be flipped so that X is major and Y is minor… in which case ‘row’ and ‘column’ are flipped… but for now let’s line them up, so to speak.

So, the purely manual way:
container.addChild(myChild, row, column);

…where row and column are ints or Integers.

That allows you to be 100% explicit but it’s a pain to create a UI that way. So, if you give it only one number then it assumes it is the column in whatever row was just created… and if you give it neither it creates a new row… as you’ve seen.

So this allows you to do stuff like:

container.addChild(new Label("Name:")); // creates a new row with a label in column 0
container.addChild(new Label(theValueOfName), 1); // adds the value to the row just created but at column 1
container.addChild(new Button("Edit"), 2); // adds the button to the row just created but at column 2

For creating UIs that’s nicer because if you decide to reorder your rows then you have less search/replacing to do on row values. But you could still do it the manual way:

container.addChild(new Label("Name:"), 0, 0);
container.addChild(new Label(theValueOfName), 0, 1); 
container.addChild(new Button("Edit"), 0, 2); 

Also note: rows and columns do not need to be contiguous and you can leave cells empty also. The layout will figure it out.

Generally, the easiest way is to just add the DragHandler as a listener. Something like:
MouseEventControl.addListenersToSpatial(myContainer, new DragHandler());

The syntax of my code samples may be a little off here and there as I’m going from memory on my non-jme computer because I’m out of town at the moment.

1 Like

Hello pspeed!

I am trying to make a slider appear, can’t seem to figure out what I am doing wrong the slider simply wont appear:

    DefaultRangedValueModel m = new DefaultRangedValueModel();//50000, 1000000, 60000);       
    Slider s = new Slider(m, Axis.X, "glass") ;       
    window.attachChild(s);
    window.addChild(new Label(String.valueOf(m.getValue())));

window.addChild(s);

Lol, it worked:

It’s not appearing where I want it to, and it’s tiny.

So, this is where I want to use it as a basic value changing slider, how do I use it as a scrollbar for a deep container? Any simple way to link middle mouse to it after?

    DefaultRangedValueModel m = new DefaultRangedValueModel(50000, 1000000, 60000);       
    Slider s = new Slider(m, Axis.X, "glass") ;       
    window.addChild(s, 4);
    window.addChild(new Label(String.valueOf(m.getValue())));

Chances are you need to nest an additional container… I’m not sure what layout you are actually going for so I can’t offer more advice than that.

Edit: also provide the rest of the code for that window because the layout looks strange even so.