# Head-Up Display (HUD)

A HUD (Head-Up Display) is part of a game's visual user interface. It's an overlay that displays additional information as (typically) 2-dimensional text or icons on the screen, on top of the 3D scene.

HUDs are used to supply players with essential information about the game state.

- Status: Score, minimap, points, stealth mode, …
- Resources: Ammunition, lives/health, time, …
- Vehicle instruments: Cockpit, speedometer, …
- Navigational aides: Crosshairs, cursor, hand, …

Not all games have, or need a HUD. To avoid breaking the immersion and cluttering the screen, only use a HUD if it is the only way to convey certain information.

You have two options how to create HUDs.

- To create full-featured user interfaces, you use Nifty GUI. (Recommended)
- If you just quickly want to display a line of text or an icon, you use the guiNode.

## HUD with Nifty GUI

The recommended approach to create HUDs is using Nifty GUI.

1. Lay out the GUI in one or several Nifty XML files.
2. Write the controller classes in Java.
3. Load the XML file with the controller object in your game's simpleInit() method.

The advantage of Nifty GUI is that it is well integrated into jME and the jMonkeyPlatform, and that it offers all the features that you expect from a professional modern user interface. The only small disadvantage is that you (currently still) have to lay out the interface in XML. You can see this as an advantage too, as it enables you to edit the user interface without editing the code afterwards.

For HUDs, you Basically follow the same instructions as for creating a normal Nifty GUI, you just don't pause the game while the HUD is up.

## The GUI Node

Using the GUI Node is the default approach in jme3 to create very simple, static HUDs. If you just quickly want to display a line of text, or a simple icon on the screen, use this no-frills method. If you want a more advanced HUD with effects and interaction, use Nifty GUI.

Next to the rootNode for the 3-dimensional scene graph, jME3 also offers a 2-dimension (orthogonal) node, the `guiNode`. This is how you use it for HUDs:

- Create a GUI element (text or image).
- Attach the GUI element to the guiNode.
- Place the GUI element in the orthogonal render queue using `setQueueBucket(Bucket.Gui)`.

The element appears as 2-D, static element on the screen.

By default, the guiNode has some scene graph statistics attached in SimpleApplication. To clear the guiNode and attach your own GUI elements, you detach all children.

    guiNode.detachAllChildren();

### Displaying Pictures in the HUD

A simple image can be displayed using `com.jme3.ui.Picture`.

    Picture pic = new Picture("HUD Picture");
    pic.setImage(assetManager, "Textures/ColoredTex/Monkey.png", true);
    pic.setWidth(settings.getWidth()/2);
    pic.setHeight(settings.getHeight()/2);
    pic.setPosition(settings.getWidth()/4, settings.getHeight()/4);
    guiNode.attachChild(pic);

When you set the last boolean in setImage() to true, the alpha channel of your image will be rendered transparent/translucent.

### Displaying Text in the HUD

You use `com.jme3.font.BitmapText` to display text on the screen.

    BitmapText hudText = new BitmapText(guiFont, false);
    hudText.setSize(guiFont.getCharSet().getRenderedSize());      // font size
    hudText.setColor(ColorRGBA.Blue);                             // font color
    hudText.setText("You can write any string here");             // the text
    hudText.setLocalTranslation(300, hudText.getLineHeight(), 0); // position
    guiNode.attachChild(hudText);

The BitmapFont object `guiFont` is a default font provided by SimpleApplication. Copy you own fonts as .fnt+.png files into the `assets/Interface/Fonts` directory and load them like this:

    BitmapFont myFont = assetManager.loadFont("Interface/Fonts/Console.fnt");
    hudText = new BitmapText(myFont, false);

### Displaying Geometries in the HUD

It is technically possible to attach Quads and 3D Geometries to the HUD. They show up as flat, static GUI elements. Note that if you use a lit Material, you must add a light to the guiNode. Also remember that size units are pixels in the HUD (a 2-wu cube is displayed 2 pixels wide).

### Positioning HUD Elements

- When positioning text and images in 2D, the bottom left corner of the screen is `(0f,0f)`, and the top right corner is at `(settings.getWidth(),settings.getHeight())`.
- If you have several 2D elements in the GUI bucket that overlap, define their depth order by specifing a Z value. You can use `pic.move(x, y, -2)` or `hudText.setLocalTranslation(x,y,-2)`.
- Size and length values in the orthogonal render queue are treated like pixels. A 20*20-wu big quad is rendered 20 pixels wide.

### Keeping the HUD Up-To-Date

Use the update loop to keep the content up-to-date.

    public void simpleUpdate(float tpf) {
      ...
      hudText.setText("Score: " + score);
      ...
      picture.setImage(assetManager, "Interface/statechange.png", true);
      ...
    }

gui, display, documentation

view online version