In this recipe, we'll develop a loading screen along with a controller for the game. It'll cover the most important aspects of the loading screen, such as showing a text and image for what it's loading and an indicator that shows the system is working.
Before starting this, it's recommended that you have a basic understanding of how to set up Nifty in an application and how to create screens and controllers. Have a look at the previous recipe, Initializing Nifty managing an options menu, if you are unsure about this.
We begin by creating the XML for the loading screen. Perform the following nine steps to do this:
loadingScreen.xml
and load Nifty-default-styles
and Nifty-default-controls
. Optionally, we can also include optionsMenu
from the previous recipe.<screen>
element:<screen id="loadingScreen" controller="gui.controller.LoadingScreenController">
<layer>
element:<layer id="layer0" childLayout="center" backgroundColor="#000f">
<layer>
element, we define <panel>
that will contain our layout. Note that we set visible
to false
:<panel id="loadingPanel" childLayout="vertical" visible="false">
<effect> <onShow name="fade" start="#00" end="#ff" length="500" inherit="true"/> <onEndScreen name="fade" start="#ff" end="#00" length="200" inherit="true"/> </effect>
<panel>
elements inside this file. At the top and bottom, there will be two black bars captioning the loading image, which will appear in the central panel.topPanel
element, we define <control name="label">
that will contain the name of the scene that is being loaded.bottomPanel
element will have an animated indicator that will show the system hasn't frozen. We will define another panel inside this, aligned to the right of the screen. We will use an imageSizePulsate
effect to animate this and have it fade in as well, as shown in the following code:<effect> <onShow name="fade" start="#00" end="#ff" length="1000"/> <onShow name="imageSizePulsate" startSize="100%" endSize="50%" pulsator="SinusPulsator" activated="true" timeType="infinite"/> </effect>
<layer>
tag beside the previous one that will contain the options
control from the previous recipe.Now, we have a complete XML. Let's have a look at the controller for this. We will create it by performing the following seven steps:
LoadingScreenController
that extends the NiftyController
class we created in the previous recipe.loadingText
and loadingScreen
, and setters for these as well.onStartScreen()
method and add the following three lines to it:screen.findNiftyControl("caption", Label.class).setText(loadingText); screen.findElementByName("centralPanel").getRenderer(ImageRenderer.class).setImage(nifty.createImage(loadingScreen, true)); screen.findElementByName("loadingPanel").setVisible(true);
NiftyAppState
method from the previous recipe, we should add the following line just after the nifty.fromXml
call:nifty.addXml("Interface/Screens/loadingScreen.xml");
convenience
class to access nifty.gotoScreen()
.gotoScreen("loadingScreen")
from our main class, we can add the following lines to set lodingText
and loadingImage
:((LoadingScreenController)niftyState.getNifty().getScreen("loadingScreen").getScreenController()).setLoadingText("Loading Test Scene"); ((LoadingScreenController)niftyState.getNifty().getScreen("loadingScreen").getScreenController()).setLoadingImage("Interface/Image/loadingScreen.png");
Most of the work in this recipe consists of getting the XML layout right. It's a good idea to sketch it on paper first and visualize the flow of the elements.
The reason the fade effect is shorter is because by the time it fades out, the game is ready to be played and the player doesn't need to wait longer than necessary. When the loading screen is first shown, the player has to wait for the game to load.
There is a reason why we set loadingPanel
to visible="false"
at the beginning and used onShow
rather than onScreenStart
effects. The onStartScreen
method in the controller is called after the screen has been started and onScreenStart
effects have been fired (and completed). This means that any fading will occur before we set the images, and they would pop into existence after some time has passed. Since the onShow
effects are called once the element becomes visible, we get around that problem this way.
Another possible gotcha here, especially if we use a test case to show the screen, is that we can't call nifty.gotoScreen
just after initializing NiftyAppState
. Since the AppState
initialization method is called in a thread-safe way, it doesn't run until the next update cycle. This means that if we try to change the screens on the next line, we will get NullPointerException
.
13.59.227.82