after having several problems with getting started I went back to the “Best Practices” and want to follow the right steps.
So I am working on my BaseGame and try to start with a GUI, having 2 Screens and every Screen it’s own custom control.
Implement generic game features in the MyBaseGame class: GUI (start screen, highscore screen), screen switching and pausing, the in-game HUD, level loading, saving and loading games, AppSettings, the main() method, etc.
StartScreen.xml and OptionsScreen.xml start with nifty tags and describe one screen each, showing only a simple text.
java.lang.ClassCastException: de.lessvoid.nifty.screen.DefaultScreenController cannot be cast to mygame.StartScreenState
at mygame.BasicGame.simpleInitApp(BasicGame.java:26)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:231)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:129)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:205)
at java.lang.Thread.run(Thread.java:662)
I appreciate any help, hints to existing projects, but the code-snippets in the documentation realy don't help me getting all the things working together...
The code snippets are more helpful when you read the text around them and not just copy/paste them. You never set the screen controller, why should you be able to get it? You get a default screen controller and that cannot be casted to your own obviously.
I try to use nifty with xml Input mainly and thought that:
should bind the Controller.
Documentation tells me it will try to find a corresponding controller (don't know where it will look ^^) and instantiate a new one else.
This does not seem to work, because my Constructor needs a SimpleApplication parameter, therefore defaultController is used and this one can't be cast to my StartScreenState.
So now I create the States beforehand and try to load Xml after the fact.
public void simpleInitApp() {
NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, viewPort);
Nifty nifty = niftyDisplay.getNifty();
StartScreenState startControl = new StartScreenState(this);
OptionsScreenState optionsControl = new OptionsScreenState(this);
As addXml doesnt take a control I have to use fromXml which works for the first startControl but can't be used a second time with a different controller.
So this approach fails for the OptionController.
Is my approach, handling nifty in the BasicGame (there is Nifty object, required by bind in the States as well) wrong and I should try to change the initialize Operations of my States or where lies the problem.
@glaucomardano:
Mine looks nearly the same. I don't use an AbstractScreenController (what did you put there) and call the Controllers State, because they are both at the same time, as proposed in the documentation.
How do you initialize nifty with the different Screen.xml files?
btw, it’s not needed to register the controllers yourself, they will be registered automatically when added to the nifty object. Then these tow lines aren’t needed:
@glaucomardano: Thanks, I tried it your way and this was the same I startet from. Triedt with controller=“package.Classname” and controller=“Classname” but the MyScreen cast fails because it tries to cast a DefaultScreenControl as did before.
I read every last line on guis, apps, states and controls in the wiki but I don’t get the examples to work.
Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.ClassCastException: de.lessvoid.nifty.screen.DefaultScreenController cannot be cast to mygame.StartScreenState
at mygame.BasicGame.simpleInitApp(BasicGame.java:42)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:231)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:129)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:205)
at java.lang.Thread.run(Thread.java:662)
and this is preceded by:
13.11.2011 13:15:09 de.lessvoid.xml.tools.ClassHelper getInstance
WARNUNG: class [StartScreenState] could not be instanziated (java.lang.ClassNotFoundException: StartScreenState)
13.11.2011 13:15:09 de.lessvoid.nifty.screen.Screen
INFO: Missing ScreenController for screen [startScreen] using DefaultScreenController() instead but this might not be what you want.
when controller="StartScreenState" and:
13.11.2011 13:20:01 de.lessvoid.xml.tools.ClassHelper getInstance
WARNUNG: class [mygame.StartScreenState] could not be instanziated (java.lang.InstantiationException: mygame.StartScreenState)
13.11.2011 13:20:01 de.lessvoid.nifty.screen.Screen
INFO: Missing ScreenController for screen [startScreen] using DefaultScreenController() instead but this might not be what you want.
when controller="mygame.StartScreenState".
As I read this, the first approach doesn't find the class and so packagename is indeed a good idea.
But still it looks like nifty can't instantiate a ScreenController that implements AbstractAppState and therefore needs a SimpleApplication parameter to it's constructor.
But still it looks like nifty can’t instantiate a ScreenController that implements AbstractAppState and therefore needs a SimpleApplication parameter to it’s constructor.
No. You are thinking bad things ;). Just do how I do. That example you saw at your first post was retired from my project, then that really work. I'm using my screen controllers as AppState as well. You simply aren't mapping your screens correctly, then the nifty uses the default screen controller instead.
If you are letting nifty instantiate your screen controller then it will need a no-arg constructor. Otherwise you have to instantiate it yourself and pass it to nifty.loadXml().