I'm trying to shows up a LoadingGameState, but it's not happening…
First of all, my game enters in MenuState, then the user have 2 options: press ESC and get out of the game or press F2 and enter the game… I want that, when the user press F2, a Loading Screen shows before enter the game, but it's not showing up. The Menu Screen continues showing up and after a short time, enter directly on the game…
here is my code for my F2 Perform Action:
private class EnterAction extends InputAction {
public void performAction( InputActionEvent evt ) {
//Desativa o Estado de Menu
meuState.setActive(false);
// Create LoadingGameState and enable
LoadingGameState loading = new LoadingGameState();
loading.setName("Loading");
GameStateManager.getInstance().attachChild(loading);
loading.setActive(true);
// Enable DebugGameState
DebugGameState debug = new DebugGameState();
GameStateManager.getInstance().attachChild(debug);
debug.setActive(true);
//Cria o estado de "Em Jogo"
GameState ingame = new InGame("InGame");
//Seta-o como ativo
ingame.setActive(false);
//Anexa-o ao GameStateManager
GameStateManager.getInstance().attachChild(ingame);
// Start our slow loading test
String status = "Started Loading";
for (int i = 0; i <= 100; i++) {
if (i == 100) {
status = "Ready!";
ingame.setActive(true);
GameStateManager.getInstance().detachChild("Loading");
} else if (i > 80) {
status = "Almost There!";
} else if (i > 70) {
status = "Loading Something Extremely Useful";
} else if (i > 50) {
status = "More Than Half-Way There!";
} else if (i > 20) {
status = "Loading Something That You Probably Won't Care About";
}
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
loading.setProgress((float)i / 100.0f, status);
}
}
}
I get this code from TestLoadingGameState of jME...
I think we need to see your Game's update/render method to tell where the problem is. My guess is that you're not calling GameStateManager.getInstance().update(tpf) in your Game.update method and/or not calling GameStateManager.getInstance().render(tpf) in your Game.render method.
What I would suggest is go back to TestLoadingGameState and start morphing back to what you have to find out what aspect of your code is causing it not to work.
I think that everything is fine, like TestLoadingGameState, the only difference is that the class TestLoadingGameState is a new Game (extends StandardGameState) and in my game, its defined like a state of GameStateManager, but it looks like it not pass by Menu State to LoadingGameState, it gets directly to the InGameState.
The only thing that is possible to see is a quick "flash" of the end (or "Loading Complete") of the LoadingGameState in MenuState… :?
I think that everything is fine, like TestLoadingGameState, the only difference is that the class TestLoadingGameState is a new Game (extends StandardGameState) and in my game, its defined like a state of GameStateManager, but it looks like it not pass by Menu State to LoadingGameState, it gets directly to the InGameState.
TestLoadingGameState is not a new game, nor does it extend StandardGameState. Does your game use StandardGame? What is your base Game?
I ran into the same problem when I was developing the transition state which extends this one. If it’s the same as what I ran into, the rendering isn’t happening while you load because your in the same thread(?).
Like this…
You disable the menu state and create and enable the loading state, but you’re working in the same thread as the rendering loop (i beleive), so nothing happens until your loading is complete. In order to continue along with the rendering you need to move the instantiation of your in game state to another thread. I posted a little sample of how I managed this here: http://www.jmonkeyengine.com/jmeforum/index.php?topic=3967.msg32158#msg32158
If you don’t wanna search for it here’s the important part:
2) As a transition from one game state to another
This took a little playing with to get to work right, but its not too bad (since I've already figured it out for you). In my case I had to make use of a thread to get the transition from the first game state into the loading state. This may not be required in other circumstances, but it was in mine. The lead in game state should still be active, as leadIn.setActive(false) will be called once the fade away is complete. It does not remove the lead in from the game state manager.
Code:
// This is called inside the current game state, i.e. a MenuState
final TransitionGameState loader =
new TransitionGameState(menuState, // <- This is the lead in game state
Thanks nymon for posting your code here, and I have tried to use your code into my game…
but I'v got the following error:
Exception in thread "Thread-4" java.lang.NullPointerException
at org.lwjgl.opengl.GL11.glMatrixMode(GL11.java:1737)
at com.jme.renderer.lwjgl.LWJGLCamera.onFrustumChange(Unknown Source)
at com.jme.renderer.AbstractCamera.<init>(Unknown Source)
at com.jme.renderer.lwjgl.LWJGLCamera.<init>(Unknown Source)
at com.jme.renderer.lwjgl.LWJGLRenderer.createCamera(Unknown Source)
at com.jmex.game.state.StandardGameState.initCamera(Unknown Source)
at com.jmex.game.state.StandardGameState.<init>(Unknown Source)
at ecas.InGame.<init>(InGame.java:164)
at ecas.MenuHandler$EnterAction$1.run(MenuHandler.java:76)
I put your code in My Input Handler, to make the changes when I click my F2 key... Here is the code:
private class EnterAction extends InputAction {
public void performAction( InputActionEvent evt ) {
final TransitionGameState loader = new TransitionGameState(meuState, Utilitarios.carregaImagem("quad_load.png"));
GameStateManager.getInstance().attachChild(loader);
loader.setActive(true);
loader.setProgress(0, "");
new Thread() {
public void run() {
this.setPriority(Thread.NORM_PRIORITY + 1);
InGame play = new InGame("play", loader); /* What I have to do HERE???*/
GameStateManager.getInstance().attachChild(play);
play.setActive(true);
loader.setProgress(1); // <- begin fade
}
}.start();
/*
//Cria o estado de "Em Jogo"
GameState ingame = new InGame("InGame");
//Anexa-o ao GameStateManager
GameStateManager.getInstance().attachChild(ingame);
//Seta-o como ativo
ingame.setActive(true);
//Desativa o Estado de Menu
meuState.setActive(false);
**/
}
}
}
On the following code line:
InGame play = new InGame("play", loader); /* What I have to do HERE???*/
I really have to pass my loader to the constructor of my InGame???? and what I have to do with this o my InGame class??? just call loader.update(tpf) on my update method of InGame???
This is because some stuff is now being made in the new thread you just created for loading the state, and a few things may need to be done specifically in the render thread. Find which statement throws the exception and use GameTaskQueueManager.getManager().update() to make that call. You should be able to find examples of that here on the forum and you may have to do this in a few places.
You dont have to pass the loader into the constructor of your gamestate, this was only so you can update the progress bar while you were "constructing", you can skip that if like.
Once you get all the GL calls done in the correct thread, it looks like you should be good to go! Let us know how it turns out.
null pointer exceptions in gl calls are almost always because of gl calls being made in threads that do not own the gl render process. In this case, your menuhandler. Make use of jme's GameTaskQueueManager and java's Callable classes and init your new state that way.
Yes, it may also help if you have access to a debugger then you can step around until you run into a problem. It's easier this way to figure this kind of stuff out, especially if you not an open gl expert (I know I'm not).
private class EnterAction extends InputAction {
public void performAction( InputActionEvent evt ) {
//If a InGame State is already created, just enter the game
if(GameStateManager.getInstance().getChild("InGame") != null)
{
//Back to Menu State
GameStateManager.getInstance().activateChildNamed("InGame");
//Deactivates Menu State (for while)
meuState.setActive(false);
}
//otherwise, creates a new InGame State
else
{
//Creates a new LoadingGameState with 10 steps
loading = new LoadingGameState(10);
loading.setActive(true);
loading.setProgress(0,"Por Favor, Aguarde..."); // center the progress bar.
GameStateManager.getInstance().attachChild(loading);
GameTaskQueueManager.getManager().getQueue(GameTaskQueue.UPDATE).setExecuteAll(true);
//Creates a new thread
Thread loader = new Thread(new LoaderThread());
loader.start();
//and a new thread with a new Callable to create the InGame State
new Thread() {
here is the secret that I was searching :-D :-D
public Object call() throws Exception {
GameState ingame = new InGame("InGame");
GameStateManager.getInstance().attachChild(ingame);
ingame.setActive(true);
return null;
}
});
}
}.start();
//Deactivate the Menu State
meuState.setActive(false);
}
}
}
Ufffffffffffffssss :D Finally I got it...... damn code :evil: