Hello World

In this Mini Tutorial you're going to create a very basic and simple Hello World Application to get used to Nifty.

Nifty Hello World

Webstart (jnlp)

Java Preparation

Create a new Java Project with you favorite IDE. For the sake of simplicity I assume you've downloaded the "complete" version of nifty. Add the nifty jar to your classpath.

Classpath

Now initialize lwjgl and set the display mode you want to use (This step is not covered here in detail because it is lwjgl-specific and is documented elsewhere ).

Create the Nifty Instance and load a XML-File

Everything you do within Nifty is done with an instance of the Nifty class. To create it you'll need to give it a RenderDevice implementation you want to use. The only supported version is RenderDeviceLwjgl but this might change in the future.

Because you can easily add sound to your nifty gui you'll need to give it a SoundSystem implementation too. There's a standard implementation available that uses Slick.

Nifty nifty = new Nifty(
    new RenderDeviceLwjgl(),
    new SoundSystem(new SlickSoundLoader()),
    new TimeProvider());

To load a xml gui file and initializes the rendering you simply use the fromXml() method of your new nifty instance. Creating the actual XML-File is covered below.

nifty.fromXml("helloworld/helloworld.xml");

Lwjgl Renderloop with Nifty

This is your basic lwjgl render loop. You'll need to call the nifty render() method once a frame. And you'll need to forward Keyboard-Events to Nifty so that it can respond to them.

This might look like this:

    boolean done = false;
    while (!Display.isCloseRequested() && !done) {
      // show render
      Display.update();
  
      // forward keyboard events to nifty
      while (Keyboard.next()) {
        nifty.keyEvent(
          Keyboard.getEventKey(), Keyboard.getEventCharacter(), Keyboard.getEventKeyState());
      }
  
      // render nifty
      int mouseX = Mouse.getX();
      int mouseY = Display.getDisplayMode().getHeight() - Mouse.getY();
      if (nifty.render(true, mouseX, mouseY, Mouse.isButtonDown(0))) {
        done = true;
      }
    }

Nifty XML

This shows the basics of the nifty xml definition for the Hello World example.

<screen>

The basic building block of a nifty gui is the concept of a Screen. A Screen is everything that is visible on the screen at a certain time or state of your GUI. For examle a Screen could be the "option menu" of your game or the credits screen.

Your usual nifty-gui consists of several screens that are interconnected. To identify every screen and to allow switching between screens each screen should have a unique name, the screen id.

The following example shows the screen of the Hello World example we're building. The Hello World example consists of only a single screen which is given the name "start". This name is special because nifty automatically looks for this name and always starts the execution of the gui with the screen named "start"

<?xml version="1.0" encoding="UTF-8"?>
<nifty>
  <screen id="start" controller="de.lessvoid.nifty.examples.helloworld.HelloWorldStartScreen">
    ...
  </screen>
</nifty>

With the "controller" attribute of the <screen> element you define the controller class for each screen. This class retrieves all events a screen might produce. So for instance if you click on elements you can define an event and this event is sent to the controller class.

More on the controller Interface below.

<layer>

Within a Screen you can have several layers of elements. So you could use a layer for your background. A layer for your menu and another layer on the top to display a logo or something like that. Layers are rendered back to front as they appear in the xml file.

For the Hello World example we only need a single layer. To make things a bit interessting we give the layer a background color. With the childLayout attribute we define the way child elements of the layer are being positioned. With "childLayout='center'" we define that the first child element of the layer is centered within the layer.

<?xml version="1.0" encoding="UTF-8"?>
<nifty>
  <screen id="start" controller="de.lessvoid.nifty.examples.helloworld.HelloWorldStartScreen">
    <layer id="layer" backgroundColor="#003f" childLayout="center">
      ...
    </layer>
  </screen>
</nifty>

<panel>

Panel is one of niftys elements. It is just a rectangular area with a width and a height. For the Hello World example we want a simple orange colored rectangle in the center of the screen. So we use a panel element for this and give it a height of 25% and 35% of the width of the parent element. In this case is the parent element the layer which is always the size of the current display mode.

<?xml version="1.0" encoding="UTF-8"?>
<nifty>
  <screen id="start" controller="de.lessvoid.nifty.examples.helloworld.HelloWorldStartScreen">
    <layer id="layer" backgroundColor="#003f" childLayout="center">
      <panel height="25%" width="35%" align="center" valign="center" backgroundColor="#f60f"
             childLayout="center" visibleToMouse="true">
        ...
      </panel>
    </layer>
  </screen>
</nifty>

What we've got so far - a colored rectangle ;)

Nifty Hello World Basic

<text>

The text element let's you output text. So we just add a "Hello World!" text to the panel and center it.

<?xml version="1.0" encoding="UTF-8"?>
<nifty>
  <screen id="start" controller="de.lessvoid.nifty.examples.helloworld.HelloWorldStartScreen">
    <layer id="layer" backgroundColor="#003f" childLayout="center">
      <panel height="25%" width="35%" align="center" valign="center" backgroundColor="#f60f"
             childLayout="center" visibleToMouse="true">
        <text font="verdana-24-shadow.fnt" text="Hello World!"
              align="center" valign="center" />
      </panel>
    </layer>
  </screen>
</nifty>

Nifty Effects

Now comes the actual fun part - adding effects! You can add effects to every element inside a layer.

You can add effects for the following events:

  • onStartScreen
  • onEndScreen
  • onHover
  • onFocus
  • onActive

onStartScreen

Let's say we want to move the orange panel from the top of the screen to the center of the screen whenever the screen becomes active. We would add a "move" effect to the panel for the onStartScreen event. So whenever the screen is started the move effects automatically moves the panel into position.

Nifty comes with a lot of build-in effects. To use these effects we need to register them. This is done like this:

<registerEffect name="move" class="de.lessvoid.nifty.effects.general.Move" />

As you might have guess is this is a very flexible way to add your own custom effects! Just implement the Effect interface, register the effect with the <registerEffect> Tag and the effect is ready to use!

So, the next thing is to add the actual onStartScreen effect to the panel:

<panel height="25%" width="35%" ...>
  <effect>
    <onStartScreen name="move" mode="in" direction="top" length="300" startDelay="0" inherit="true"/>
  </effect>

With the "name" attribute you add the registered effect. All other attributes are effect specific. For the "de.lessvoid.nifty.effects.general.Move" effect you can for example define the direction from where it should move in or out. You can give a start delay and and effect length time in ms. The inherit flag defines if the effect travels to all child elements or if it is limited only to the element you attached the effect too.

In the example above the panel moves in from the top of the screen. The effect starts immediately and takes 300 ms. The effect is not limited to the panel and moves all child elements. In this example the "Hello World!" text is moved together with the panel.