Application State : Doc error

In the AppState tutorial, in the update method of TestAppStates Class the code is following,



[java] public void update(){

super.update();

stateManager.update(tpf);

stateManager.render(renderManager);

renderManager.render(tpf);

}

[/java]



I am not sure, but shouldn’t there be a line defining, what tpf is. The following,



[java]float tpf = timer.getTimePerFrame();[/java]



Application Class doesn’t define it.

Removed my other post because I was full of crap.



This tutorial needs a rewrite I think. There is no need to manually invoke the state manager since it’s already built in to Application.

Save someone else some time trying to figure out what we’re talking about… this tutorial:

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:application_states?s[]=testappstates



And this class:

Google Code Archive - Long-term storage for Google Code Project Hosting.



…which now could be 90% smaller or something.

Now, I have 2 question,


  1. is the float tpf = timer.getTimePerFrame(); should be in the update() method of classes, who are subclassing Application?


  2. I didn’t find lines like ,



    [java]stateManager.update(tpf);

    stateManager.render(renderManager);[/java]

    in the Application. So, I don’t understand what did you say by “…already built in to Application.”

No, you’re right. I saw that it had references so AppStateManager and then stopped there. It never occurred to me that it would hold a state manager and then never do anything with it.



I don’t think anyone should be using Application directly, actually. SimpleApplication is 1000 times superior and does handle state manager for you. SimpleApplication should be called Application and Application should be renamed to PainfulIfUsedDirectly or something. :wink: People see “simple” and they avoid it but it’s the “one everyone should use”.

1 Like

But note: now I’m also not sure what the original issue is…

Application does have a protected timer field. And TestAppStates does have:

[java]

public void update(){

super.update();

// do some animation

float tpf = timer.getTimePerFrame();

stateManager.update(tpf);

stateManager.render(renderManager);

// render the viewports

renderManager.render(tpf);

}

[/java]

So I maybe just shouldn’t answer posts until I’m more awake. :stuck_out_tongue:



Edit: ah… just a documentation problem. Sorry.

The SimpleApplication class has these lines in its update method,



[java] stateManager.update(tpf);

stateManager.render(renderManager);



renderManager.render(tpf)[/java]



I am trying to learn and implement my own Application States. But, I am getting confused. In the example, there is just the node. Is a state is just about a changing the rootNode and what the main program has in its update loop?

An AppState is an application-global “thing” that can do stuff.



For example, a HUD could be an app state. I’ve posted before a ViewportState that does everything for you to setup a new Viewport so you don’t have to manage it yourself. Every one of my GUI screens is an AppState… and in fact even my game itself is an AppState.



In my case, all my main application class does is setup a few app states.



So an AppState can do anything, really. It’s a non-node specific way of hooking into the update loop and life cycle of the application.



Edit: as opposed to Control which is a node-specific way of hooking into the update loop, etc.

I am thinking it in this wUD is a state, and in-game is a state. So, there is a big difference between what we see. Again what we see is what is attached to the node(rootNode). So, with the change of every State, we are just changing the children of the rootNode. That’s why we have a node in AppState example. Is it correct?



Did you used the word ‘non-node’ in the same way?

An app state might do nothing at all with scene nodes. For example, my ViewportState just sets up a viewport and its own rootNode for that viewport, it’s own camera, etc… it never does anything at all with Application’s root node. It enables and disables the viewport based on the enabled state of the AppState… and anything wanting to show things in that viewport need only access the state and its root node. (and these other things in my case are also app states)



So it just depends on what the app state is doing. A control on the other hand is always associated with a specific node/spatial.



Even in your example, a HUD might only do things with the guiNode and not rootNode at all. Or it may set up its own viewport on top of everything else. It has access to Application (and can cast it to SimpleApplication or your own app class if needed) and so can get anything it needs from the global application stuff.

Here is where I posted my ViewPortState if it helps:

http://test.hub.jmonkeyengine.org/groups/graphics/forum/topic/can-i-render-an-object-ontop-of-everything-but-under-gui/?topic_page=2&num=15

@pspeed oh, sorry. I made a mistake. Its not HUD, I was talking about the Main Menu. It should be another state with all its assets attached with the rootnode, isn’t it?

Actually, my MainMenuState is a nifty screen controller. It intercepts all of the nifty events and then when it’s done it adds the GameState and the LoadingState and removes itself. Then when LoadingState is done (which is another nifty ScreenController) it closes itself leaving the GameState to run the game.



Of all of those, only the game state does anything with the root node.



If you are constructing your own menus then they are likely in the guiNode.



…but that’s not really the point. Of course an AppState can do stuff with the rootNode but I think the majority of them won’t be.

2 questions,

  1. when exactly I need to use “ViewPort object”?
  2. why do I need to state(while subclassing Application class) different update states of different manager(renderManager.update(tpf), stateManager.update(tpf)). Why they are not called inherently as the game runs? They are always needed to be updated no matter what the user doing. isn’t it?
iamcreasy said:
2 questions,
1. when exactly I need to use "ViewPort object"?


You use it if you need a layer on top of other layers. I use it to have a 3D gui window on top of my scene, for example.

iamcreasy said:
2. why do I need to *state*(while subclassing Application class) different update states of different manager(renderManager.update(tpf), stateManager.update(tpf)). Why they are not called inherently as the game runs? They are always needed to be updated no matter what the user doing. isn't it?


Application is the "SuperBasicaPainToUseDirectly" class that you should not use except under extremely specific circumstances. SimpleApplication is what you should use in 99% of cases because it does all of that for you. I don't know why Application doesn't do these things except maybe subclasses need to insert some specific processing or control order in a different way.

...but really, use SimpleApplication.
1 Like
pspeed said:
You use it if you need a layer on top of other layers. I use it to have a 3D gui window on top of my scene, for example.


What layers are on top on one another by default(When a blank canvas of simple app is run.)? I am asking this because, I'm curious how all the process break down to simpler pieces.


Application is the "SuperBasicaPainToUseDirectly" class that you should not use except under extremely specific circumstances. SimpleApplication is what you should use in 99% of cases because it does all of that for you. I don't know why Application doesn't do these things except maybe subclasses need to insert some specific processing or control order in a different way.

...but really, use SimpleApplication.


It just came into my mind...why don't you propose this as an official change? :)
iamcreasy said:
What layers are on top on one another by default(When a blank canvas of simple app is run.)? I am asking this because, I'm curious how all the process break down to simpler pieces.


I'm not sure, exactly. I know there is at least a main ViewPort (which is where rootNode is) and a gui ViewPort (which is where the guiNode is).

In Mythruna, I create a ViewPort that I use as a 3D GUI, and I create it as an additional "main" view. So it gets rendered on top of rootNode but underneath guiNode. (the normal gui viewport is a post view.)

Poke a little around RenderManager if you are more curious how things come together.

Sorry to bring up this post, but I was wondering if it’s possible to share a sample AppState example? :x I got confused after going around searching for how to enable appstates classes when i tried to figure how to implement it onto my game…



Here are a few questions that I’m unsure about:

  1. I noticed that the classes that implements AbstractAppStates has the various methods overridden – start(), initialize()… etc… Are these really overriden methods or self-created?


  2. Also, if say, some of these classes implements ScreenController, do I have to bring in all the assets (e.g. assetManager, inputManager…) from the running class (with SimpleApplication extended) in order to initialize nifty’s display class object?


  3. I noticed people typing “setEnable()” around, is that a a self-written method as well … or?



    Thanks!

Have you looked at the javadoc for any of these classes?



http://hub.jmonkeyengine.org/javadoc/com/jme3/app/state/AbstractAppState.html

http://hub.jmonkeyengine.org/javadoc/com/jme3/app/state/AppState.html



I sort of feel like all of the “self-written” questions can be answered right there and it would work better to start from there.

pspeed said:
Have you looked at the javadoc for any of these classes?

http://hub.jmonkeyengine.org/javadoc/com/jme3/app/state/AbstractAppState.html
http://hub.jmonkeyengine.org/javadoc/com/jme3/app/state/AppState.html

I sort of feel like all of the "self-written" questions can be answered right there and it would work better to start from there.


Thanks for the reply. :)

Lol, the thing is, yes I did.. I was reading the javadoc of AbstractAppState/AppState on the platform and the setEnabled, etc.. didn't exist but after looking through the link you gave me and the one I was reading on the platform, then I realize that on the platform's javadoc, it was written as setActive instead of setEnable. Truly it worked better starting from here, I pretty much get the idea around now, just getting a few nullpointers here and there though, especially when trying to get a nifty-class appstate working to produce a sample screen to see if I got the idea correctly.

Somehow, niftydisplay is showing but funny, the screen keeps on running up and down... like it keeps on refreshing on the spot.. and the nifty log showing on the output keeps on sewing nifty data but I don't see where it has the screen's y-axis decrementing/incrementing.. here's a screenshot:



I am... definitely doing something wrong with the appstates and nifty wrongly eh..? :/

Here is the XML of a simple start/end screen:
[xml]
<screen id="start" controller="TestPack4.Menu">
<layer id="layer" backgroundColor="#0030" childLayout="center">
<panel id="panel" height="25%" width="35%" align="center" valign="center" backgroundColor="#f60f" childLayout="center" visibleToMouse="true">
<interact onClick="quit()"/>

<effect>
<onStartScreen name="move" mode="in" direction="top" length="300" startDelay="0" inherit="true"/>
<onEndScreen name="move" mode="out" direction="bottom" length="300" startDelay="0" inherit="true"/>
<onHover name="pulsate" scaleFactor="0.008" startColor="#f600" endColor="#ffff" post="true"/>
</effect>
<text id="text" font="Interface/Fonts/Verdana.fnt" color="#000f" text="Hello World!" align="center" valign="center" />
</panel>
</layer>
</screen>

<screen id="end" controller="TestPack4.Menu">
<layer id="layerB" backgroundColor="#ff30" childLayout="center" >
<image filename="Interface/profile2.jpg" align="left" valign="center" width="40%"/>
</layer>
</screen>
[/xml]

and the appstate with screencontroller
[java]
public class Menu extends AbstractAppState implements ScreenController {

protected boolean initialize = false;
private Nifty nifty;

public Menu(){
}

@Override
public void initialize(AppStateManager stateManager, Application app) {
NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(app.getAssetManager(),
app.getInputManager(),
app.getAudioRenderer(),
app.getGuiViewPort());

nifty = niftyDisplay.getNifty();
nifty.fromXml("Textures/NiftyTest7.xml", "start", this);
app.getGuiViewPort().addProcessor(niftyDisplay);
System.out.println("HELLO!");
initialize = true;
}

public boolean isInitialize(){
return initialize;
}

public void bind(Nifty nifty, Screen screen) {
}

public void onStartScreen() {
}

public void onEndScreen() {
}

public void quit(){
nifty.gotoScreen("end");
}
}
[/java]


...plus a sample running class:
[java]
public class RunningApp extends SimpleApplication{

public RunningApp(){}
private Menu m;
public static void main(String args[]){
RunningApp ra = new RunningApp();
ra.start();
}

@Override
public void simpleInitApp() {
m = new Menu();
System.out.println("Init? "+m.isInitialize());
stateManager.attach(m);
flyCam.setDragToRotate(true);
flyCam.setMoveSpeed(30);
}
}
[/java]