Handling a game message queue

It is possible to relay most game-related information to the player using a console. However, it's a very basic form of communication. Modern players often expect more graphical ways of receiving information. In this recipe, we'll explore one way of doing this using Nifty. We'll create a dynamic message queue with messages moving in from the right of the screen and fading out once clicked.

It actually doesn't require that many lines of code.

How to do it...

The XML for this recipe can be completed by performing the following five steps:

  1. We start by defining a new <controlDefinition name="gameMessage">.
  2. Inside this, we should add a panel element, and inside this panel element, add two <control name="label"> elements with the ID #title and other contents.
  3. The panel should also have two effects, one onShow trigger and one onHide trigger with move and fade effects respectively, as shown in the following code:
    <onShow name="move" mode="fromOffset" offsetX="1500" length="100" inherit="true"/>
    <onHide name="fade" start="#ff" end="#00" length="100" inherit="true"/>
  4. In addition to the gameMessage control, we can define another control to be our messageQueue element. It just needs a horizontally aligned panel, spanning the whole screen.
  5. To make them align with each other, the messageQueue control is added to the mainScreen.xml file inside the same layer as the console.

    Inside MainScreenController, we need to do the following changes:

  6. First, add a new int field called messageIndex.
  7. Then, we need two methods. One of these is called addMessage that should take a string as an input.
  8. Inside the addMessage method, we define a ControlBuilder method called messageBuilder. This will create gameMessage controls:
    messageBuilder = new ControlBuilder("gameMessage") {{
      id("message"+messageIndex);
      interactOnClick("removeMessage("+messageIndex+")");
    }};
  9. After calling the build method on this and supplying the messageQueue element as the parent, we can call element.findNiftyControl to set the title and the text on the labels inside the gameMessage control.
  10. Then, we call element.show() and increase messageIndex for the next message.
  11. The second method we create is removeMessage. It takes a string called id as the input.
  12. Inside this, we use screen.findElementByName to find the message, and call hide.
  13. While doing this, we supply a new EndNotify object, which in its perform message should call markForRemoval() on the message and also layoutElements() on the parent messageQueue control.

How it works...

Once the addMessage method is called in the Controller class, ControlBuilder creates a new gameMessage instance. The interactOnClick element tells gameMessage to call removeMessage when clicked, supplying its index as id.

After its built and added to messageQueue, we populate the title and content elements of the message. Using # in the ID of these elements is preferred by Nifty for non-unique IDs.

The gameMessage instance is not visible upon creation, and we call show() to make it play the onShow effect we defined.

The Move effect is set up to have offsetX, which is outside of the screen. If it's too low, there will be a pop effect as it comes into existence. It's set to reach the target position in 100 ms. Messages will stack up nicely without any additional work when they are added.

The messages are set to disappear when clicked, as defined in the builder, through the interactOnClick method. Instead of just removing them, we want to play a short fade effect to make the transition smoother. Simply hiding them won't be enough in this case either. Since they still occupy a position in the messageQueue panel, the remaining messages won't align properly.

Hence, we want to call markForRemoval on the gameMessage element. Doing this instantly, however, would remove it before our hide effect is played. This why we supply an EndNotify object that is handled once the hide effect is done with playing; then, we add the markForRemoval call in here instead.

There's more…

Let's say we would like to be able to show messages in a window, either when clicking the message in the queue, or any time. In that case, we can use Nifty's window control.

We can define a new controlDefinition in our gameMessageControls.xml file and call it messageWindow. Inside this, we'll add <control name="window">, inside which we can add any content we'd like. For now, we can settle with <control name="label"> for text content and a short fade effect when showing or hiding the window.

Then, we can copy the addMessage method to MainScreenController, and instead of having ControlBuilder make gameMessage, we can tell it to build a messageWindow window instead.

We don't need an interactOnClick element, as the window can be closed by default. Instead, we can use it to set the title of the window:

set("title", "Window"+windowIndex);

Windows are also draggable by default, but the parent element must have childLayout="absolute" for it to work, as it lets the element decide its position itself.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.239.44