Nifty gui and SimpleUpdate

Hello guys ,



i have a collision on my simpleupdate class (based on simpleapplication ) in JME3 that is trying to load a nifty menu i made when the collision is coming.



But Nifty should be initialized on simpleinitapp() , and if i try to put in simpleupdate i have a strange loop on my menu loaded.



I know that the menu should be initialized here



[java]

@override

public void simpleInitApp() {

SetupInterface(); // initializing nifty menu

}

[/java]



But if i do my collision here how am i suppose to setup my menu outside the simpleupdate ?

[java]

@override

public void simpleUpdate(float tpf){

Collision();

}

[/java]



Thanks in advance



Edit : I was thinking of <interact , but since there is only “onclick” it doesn’t match with what i want also i don’t know how to interact in the opposite way since <interact is from Xml to Java only and not to Java to Xml

Hello,

Create your Xml screen with a screen empty and your others screens :

Example :

[xml]

|nifty|

|useStyles filename=“assets/Templates/Styles/ae-styles.xml” /|

|useControls filename=“nifty-default-controls.xml” /|



|screen id=“hide” controller=“com.didigame.acariaempire.gui.battle.StartBattleToolbarEltController” /|

|screen id=“start” controller=“com.didigame.acariaempire.gui.battle.BattleStarter” |



|!–

Background layer

–|

|layer id=“backgroundLayer” childLayout=“center” height=“100%” width=“100%” |

|panel height=“10%” width=“100%” align=“center” valign=“bottom” childLayout=“center” visibleToMouse=“true”|

|image height=“100%” width=“100%” filename=“sidebar.jpg” imageMode=“normal” /|

|/panel|

|/layer|



|!–

Image layer

–|

|layer id=“imageLayer” childLayout=“center” height=“100%” width=“100%” |

|panel height=“10%” width=“100%” align=“center” valign=“bottom” childLayout=“center” visibleToMouse=“true”|

|control id=“btnStartBattle” type=“button” label=“Start Battle!” style=“ae-button” height=“60%” width=“70%” align=“center” valign=“center” |

|interact onClick=“startBattle()” /|

|/control|

|/panel|

|/layer|

|/screen|



|/nifty|

[/xml]





Then, setup your Nifty inside the simpleInitApp method and load the screen ‘hide’

[java]

@override

public void simpleInitApp() {

SetupInterface(); // initializing nifty menu

nifty,fromXml( “myFile.xml”,“hide”);

}

[/java]



And during the simple update :

[java]

@override

public void simpleUpdate(float tpf){

if( Collision() )

{

if( nifty.getCurrentScreen().getScreenId().equals( “hide” )

nifty.goToScreen(“myRealScreen”);

}

[/java]



Hope it answers your question

2 Likes

Thank you so much , that was very clever ! And of course it’s work.



Your answer was so far one of the best answer i have seen on this forum ,







I have a few more questions if you don’t mind since i seems to know a lot about nifty :


  1. Is there a way to interact with java automaticly without clicking on anything ? i mean without <interact onclick = myfunction() , is there a way i say to my xml to execute the function without having any action to do ? ( for example i could have a Box saying FIGHT like 3 seconds and after a fade another function is invoked for example a menu ).


  2. Do we know what attributes "“haves ? i tried on all nifty wiki / forum to have something and didn’t find out. I know only " onclick and onClickAlternateKey”.


  3. How do we map inputs key ? i already mapped in my game some keys and i want to use them to do some action while my menu is summoned.



    Thank you again !

Hello,

On each screen in your XML, you can specify a controller.

[xml]

|screen id=“start” controller=“com.didigame.acariaempire.gui.battle.BattleStarter” |

[/xml]

But, when you load your nifty, you can specify wich instance you want to use for each one of your screens

Example :



[java]

public class MyGame extends SimpleApplication

{

private BattleStarter controller;



public MyGame()

{

controller = new BattleStarter();

}

[…]

@override

public void simpleInitApp() {

SetupInterface(); // initializing nifty menu

nifty.fromXml( “myFile.xml”,“hide”);

nifty.getScreen(“myRealScreen”).setScreenController( controller );

}

[…]

@override

public void simpleUpdate(float tpf){

if( Collision() )

{

if( nifty.getCurrentScreen().getScreenId().equals( “hide” )

nifty.goToScreen(“myRealScreen”);

}

else if( ActionTriggered() )

{

controller.doAction();

}

}

[/java]



It’s the simple way to do it I think.



But there is a little problem when you begin to have a real complex gui ( with many xml files ) :

You have to know in advance all the ScreenController you will use.



The other solution would be to have a thread collecting events in your game and redirecting the events to each ScreenController that have registered it self to your EventController.

If you need somthing like that, I could start to explain but it is more complicated.

2 Likes

not sure i understood what is the type BattleStarter ( if it’s from nifty or not ) but i’ll try this when i get home thanks a lot

‘BattleStarter’ is just an example.

It is the name of your controller. It’s one of your classes.

You just need to implements the interface ScreenController.



For the attributes possibilities for each Xml element, you can check the file nifty.xsd link



For the input keys, you can do it the same way as for the other actions or use the attribute ‘onClickAlternateKey’ but I don’t have used it yet and don’t know how it works.

How am i suppose to read the .xsd , i have a white screen when i click on the link .

I still don’t understand how do we map an action and how we define an action ?



For example i have a menu that invokes another menu when i push enter by selecting one of the item ( items are labels )



Since in all example i found only “onclick” parameter for the labels interact , i wish i could so something with the controller.



Sorry i’m new at this thanks in advance ,



Danath.

I’m doing something like wqhat you want in my chat client already.

I have a ChatLineController which handles displaying a line in the chat window. On this controller I have a method called receivedText. This method is in charge of displaying the received text on the screen.

What I do next is, in my main class, use a reference to this controller and just call that method. This should work easy for any Nifty functionality you want to be able to use from outside the controller.

I am using a very specific and dedicated controller, but I don’t see why this wouldn’t work on a more global level like a ScreenController.



If you need a more basic code example let me know and I’ll see what I can do for you.

Hello the xsd is a text format What I provided you is a link where the nifty page where you can find it.



Open it with any text editor.

It contains the information about what XML elements are available.

ractoc said:
I'm doing something like wqhat you want in my chat client already.
I have a ChatLineController which handles displaying a line in the chat window. On this controller I have a method called receivedText. This method is in charge of displaying the received text on the screen.
What I do next is, in my main class, use a reference to this controller and just call that method. This should work easy for any Nifty functionality you want to be able to use from outside the controller.
I am using a very specific and dedicated controller, but I don't see why this wouldn't work on a more global level like a ScreenController.

If you need a more basic code example let me know and I'll see what I can do for you.


I'd really love to ! I have only one class for the moment , i'm loading nifty gui there , and the menu is appearing correctly , now i want to control it.
i'm using one of the examples controller so it's working , but i would like to have my own , some code would be helpful thanks !

didialchichi said:
Hello the xsd is a text format What I provided you is a link where the nifty page where you can find it.

Open it with any text editor.
It contains the information about what XML elements are available.


I'll do that when i return home thanks a lot !

Ok, let me post two files and a few snippets.



Here is the Nifty Control configuration for my message box:

[edit]

Ok, I’m linking this one to my SVN, for some reason, it won’t display the xml in here.

message-box-control.xml

[/edit]



And here is the control class that goes with it:

[java]

package com.ractoc.opengamefinder.client.screens.controllers;



import java.util.Properties;



import de.lessvoid.nifty.Nifty;

import de.lessvoid.nifty.controls.Controller;

import de.lessvoid.nifty.elements.ControllerEventListener;

import de.lessvoid.nifty.elements.Element;

import de.lessvoid.nifty.elements.render.ImageRenderer;

import de.lessvoid.nifty.elements.render.TextRenderer;

import de.lessvoid.nifty.input.NiftyInputEvent;

import de.lessvoid.nifty.render.NiftyImage;

import de.lessvoid.nifty.screen.Screen;

import de.lessvoid.xml.xpp3.Attributes;



public class MessageController implements Controller {

private Nifty nifty;

private Screen screen;

private Element element;



public void bind(final Nifty niftyParam, final Screen screenParam, final Element newElement,

final Properties properties, final ControllerEventListener newListener,

final Attributes controlDefinitionAttributes) {

nifty = niftyParam;

screen = screenParam;

element = newElement;

}



@Override

public boolean inputEvent(NiftyInputEvent arg0) {

// TODO Auto-generated method stub

return true;

}



@Override

public void onFocus(boolean arg0) {

// TODO Auto-generated method stub



}



@Override

public void onStartScreen() {

}



public void setMessageText(String text) {

element.findElementByName(“message-text”).getRenderer(TextRenderer.class).setText(text);

}



public void setMessageIcon(String icon) {

NiftyImage newImage = nifty.getRenderEngine().createImage(icon, false);

Element element = screen.findElementByName(“message-icon”);

element.getRenderer(ImageRenderer.class).setImage(newImage);

}



public void showMessage(String text, String icon) {

setMessageText(text);

setMessageIcon(icon);

screen.addPopup(element, element.findElementByName(“message-button”));

element.show();

}



public void hideMessage() {

element.hide();

setMessageText("");

screen.closePopup(element, null);

}

}

[/java]



In the controller, there are a few methods that interact with the screen and the element:

  • setMessageText
  • setMessageIcon
  • showMessage
  • hideMessage



    The first three are triggered from outside the controller, from another Java class. The last one is triggered by the button on the message box.

    Both the showMessage and the hideMessage method have a call to the screen, the other two only interact with the messagebox element itself.



    Now for the code snippets:

    [java]

    Element errorPanel = nifty.getCurrentScreen().findElementByName(“error”);

    MessageController errorController = errorPanel.findControl(“errorPanel”, MessageController.class);

    errorController.showMessage(“error:” + eMsg.getErrorMessage(), “resources/error.jpg”);

    [/java]



    This piece of code uses a reference to Nifty itself on the first line to get the error element on my current screen. From this elemeet I then get the MessageController through the findControl method. You can get your own controller through here, you just have to provide the controller class you are trying to find and the name of the element the controller is linked to.

    Next, I call a method on this controll. This method takes care of setting up the text and the icon on the control and displays the control, as you ahve seen in the controller code.



    I hope this clear things up a but more.



    Mark



    PS.



    You are more then welcome to browse through my code and see if there are parts you can re-use. If you are finding it hard to read or hard to understand let me know and I’ll see if I can clarify things, or rewrite pieces of code / javadoc / comments to make things more clear. If I am ever to atract extra people on this project, it needs to be easy to read and understand
2 Likes

Thank you very much mark for all of this explanation , but i still don’t understand how do you map controls for example Using arrow to browse the menu created



Your code rocks so much i understand a lot of things thanks to you ! (execpt for input mapping )

If i can see the code instead de.lessvoid.nifty.input.mapping.MenuInputMapping and de.lessvoid.nifty.controls.MenuItemControl that would help me like hell !

Well, at the moment, I don’t have a menu as such, just some buttons which I traverse with the this is default behaviour which works out of the box.



I do use the key to send messages from a textfield, for this your class needs to implement KeyInputHandler and you need to override the following method:

[java]

public boolean keyEvent(NiftyInputEvent inputEvent) {

if (inputEvent == NiftyInputEvent.SubmitText) {

sendText();

return true;

}

return false;

}

[/java]



Mark

Thanks mark this will also help ! do you know how to switch from an label to another ?

Each element has a method “public void setFocus()”. You can use this method to set the focus to a particular element. Since a Label is an Element, it should have this method as well.

Is there somewere an example of a menu i can see ?

There’s a menu in the JME test packages somewhere. Not sure if that’s the kind of menu you are looking for though, but it’s a starting point.

i really damn need the code of de.lessvoid.nifty.input.mapping.MenuInputMapping and de.lessvoid.nifty.controls.MenuItemControl , if Anyone has it please copy and paste , the solution is in there thanks …

or…you can download the source http://sourceforge.net/projects/nifty-gui/files/nifty-gui/1.2/sources/