[SOLVED]Nifty Loading screen (Progress bar)

Now that my game takes a few seconds to load i now need to implement a loading screen. I was trying to use the progress bar from the nifty tutorial.



[java]public class MainMenu implements ScreenController {



public Nifty nifty;

private TestingPhysicsCollisions myApp;

private Element progressBarElement;

private NiftyJmeDisplay niftyDisplay;

private Future future = null;

private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);



public MainMenu() {

myApp = TestingPhysicsCollisions.getApp();



niftyDisplay = new NiftyJmeDisplay(myApp.getAssetManager(),

myApp.getInputManager(),

myApp.getAudioRenderer(),

myApp.getGuiViewPort());

nifty = niftyDisplay.getNifty();



nifty.fromXml(“Interface/hellojme.xml”, “start”, this);



myApp.getGuiViewPort().addProcessor(niftyDisplay);

}



@Override

public void bind(Nifty nifty, Screen screen) {

final Element element = null;

progressBarElement = nifty.getScreen(“loadlevel”).findElementByName(“progressbar”);

}



@Override

public void onStartScreen() {}



@Override

public void onEndScreen() {}



public boolean inputEvent(final NiftyInputEvent inputEvent) {

return false;

}



public void setProgress(final float progress) {

final int MIN_WIDTH = 32;

int pixelWidth = (int) (MIN_WIDTH + (progressBarElement.getParent().getWidth() - MIN_WIDTH) * progress);

progressBarElement.setConstraintWidth(new SizeValue(pixelWidth + “px”));

progressBarElement.getParent().layoutElements();

}



public void showLoadingMenu() {

nifty.gotoScreen(“loadlevel”);



if (future == null) {

future = executor.submit(loadTrack);

} else if (future != null) {

if (future.isDone()) {

future = null;

} else if (future.isCancelled()) {

future = null;

}

}

}



private Callable<Void> loadTrack = new Callable<Void>() {



@Override

public Void call() throws Exception {



myApp.enqueue(new Callable<Void>() {

@Override

public Void call() throws Exception {

myApp.loadLevel(levelManager.getCurrentLevel());

nifty.gotoScreen(“end”);

return null;

}

});



return null;

}

};

}[/java]



heres the function which does the loading.

[java] public void loadLevel(int level) {



stateManager.attach(bulletAppState);

mainMenu.setProgress(0.1f);



soundManager.loadSoundEffects(new Sound[]{Sound.DEMO_SFX_2, Sound.DEMO_SFX_1});

mainMenu.setProgress(0.2f);



soundManager.loadMusic(new Sound[]{Sound.DEMOTRACK_1});

mainMenu.setProgress(0.4f);



levelManager.initialise(level);

mainMenu.setProgress(0.6f);



transformManager.initialise();

mainMenu.setProgress(1);

GameState.setGameState(GameState.RUNNING);

}[/java]



I have 2 problems with this:

1 - After i press “play”, the progress bar appears, but does nothing.

2 - The new thread I create never stops, it still runs even after i close the program.



I try to avoid multithreading at all costs, is it unavoidable here? and I am even using it right? Without using another thread i never see the progress bar appear, i just see the main menu freeze and then the game starts. Thanks for any info.

Ok i think I have solved it, using something i learned recently :P, adding it over a course of frames, also without threads woopy, for anyone interested.



[java] public class MainMenu implements ScreenController {



public Nifty nifty;

private TestingPhysicsCollisions myApp;

private Element progressBarElement;

private NiftyJmeDisplay niftyDisplay;



public MainMenu() {

myApp = TestingPhysicsCollisions.getApp();



niftyDisplay = new NiftyJmeDisplay(myApp.getAssetManager(),

myApp.getInputManager(),

myApp.getAudioRenderer(),

myApp.getGuiViewPort());

nifty = niftyDisplay.getNifty();



nifty.fromXml("Interface/hellojme.xml", "start", this);

myApp.getGuiViewPort().addProcessor(niftyDisplay);

}



@Override

public void bind(Nifty nifty, Screen screen) {

final Element element = null;

progressBarElement = nifty.getScreen("loadlevel").findElementByName("progressbar");

}



@Override

public void onStartScreen() { }



@Override

public void onEndScreen() { }



public boolean inputEvent(final NiftyInputEvent inputEvent) {

return false;

}



public void setProgress(final float progress) {

final int MIN_WIDTH = 32;

int pixelWidth = (int) (MIN_WIDTH + (progressBarElement.getParent().getWidth() - MIN_WIDTH) * progress);

progressBarElement.setConstraintWidth(new SizeValue(pixelWidth + "px"));

progressBarElement.getParent().layoutElements();

}



public Nifty getNifty() {

return nifty;

}



public void showLoadingMenu() {

nifty.gotoScreen("loadlevel");

myApp.loadLevel(levelManager.getCurrentLevel());

}

[/java]



In my main class

[java]

public void loadLevel(int level) {

load = true;

}



public void simpleUpdate(float tpf) {

if (load == true) {



if (frameCount == 1) {

AmbientLight ambient = new AmbientLight();

ambient.setColor(ColorRGBA.White);

rootNode.addLight(ambient);

} else if (frameCount == 2) {

stateManager.attach(bulletAppState);

mainMenu.setProgress(0.2f);

} else if (frameCount == 3) {

soundManager.loadSoundEffects(new Sound[]{Sound.DEMO_SFX_2, Sound.DEMO_SFX_1});

mainMenu.setProgress(0.3f);

} else if (frameCount == 4) {

soundManager.loadMusic(new Sound[]{Sound.DEMOTRACK_1});

mainMenu.setProgress(0.4f);

} else if (frameCount == 5) {

levelManager.initialise(level);

mainMenu.setProgress(0.6f);

} else if (frameCount == 6) {

transformManager.initialise();

GameState.setGameState(GameState.RUNNING);

mainMenu.setProgress(1f);

mainMenu.getNifty().gotoScreen("end");

}



frameCount++;

}[/java]

2 Likes

Brilliant. I was just going to work on it. :slight_smile: Thanks a lot.



How about you write a “Hello Loading” tutorial :smiley: It should be fun and easy for you.

i suppose i could write a testcase which loads a previous tutorial that takes some time to load, with some brief info, and then someone else (maybe zathura) can improve it to make it look hawt <3.

Yeh, that would be nice :slight_smile:

1 Like

fun? easy? i doubt that very much :D. Tbh all i did was follow the progress-bar tutorial on the nifty wiki, and load the level over many frames. Which is probably not even the proper way to do it, its just the only way i could get it to work properly, i tried appstates and multi-threading, but suck at both :D. But definitely doing stuff over many frames should be in the wiki, it’s a very useful thing to know for noobs like me who don’t understand how the graphics pipeline works.

2 Likes

hmm…I am also learning Nifty(the Java way). Had my one example posted there. And it was really fun. It doesn’t have to be gooood, just a head start for everyone out there…you know.

1 Like

there you go, the worst entry in the wiki :smiley:

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:loading_screen



i also didn’t know how to get back to normal flycam from nifty (thats how much i suck)

2 Likes

I will try to update it, when i m done implement it one my game. :slight_smile:

1 Like

I added the multithreaded version to the wiki, didn’t test it though.

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:loading_screen

3 Likes

oh nice, well it works great :D, thx

i updated it a bit, adding some text underneath and changing the progress bar to red so people can see it.

1 Like

i have a diffrent question:



@wezrule presented one way to do progressing of code:

[java]

public void simpleUpdate(float tpf) {

if (load == true) {



if (frameCount == 1) {

AmbientLight ambient = new AmbientLight();

ambient.setColor(ColorRGBA.White);

rootNode.addLight(ambient);

} else if (frameCount == 2) {

stateManager.attach(bulletAppState);

mainMenu.setProgress(0.2f);

} else if (frameCount == 3) {

soundManager.loadSoundEffects(new Sound[]{Sound.DEMO_SFX_2, Sound.DEMO_SFX_1});

mainMenu.setProgress(0.3f);

} else if (frameCount == 4) {

soundManager.loadMusic(new Sound[]{Sound.DEMOTRACK_1});

mainMenu.setProgress(0.4f);

} else if (frameCount == 5) {

levelManager.initialise(level);

mainMenu.setProgress(0.6f);

} else if (frameCount == 6) {

transformManager.initialise();

GameState.setGameState(GameState.RUNNING);

mainMenu.setProgress(1f);

mainMenu.getNifty().gotoScreen(“end”);

}



frameCount++;

}[/java]





Is there any class to do it automaticly? somethin like



[java]

class ProgressBar extends ProgressCode {

public void executeCode(){

AmbientLight ambient = new AmbientLight();

ambient.setColor(ColorRGBA.White);

rootNode.addLight(ambient);

stateManager.attach(bulletAppState);

mainMenu.setProgress(0.2f);

soundManager.loadSoundEffects(new Sound[]{Sound.DEMO_SFX_2, Sound.DEMO_SFX_1});

mainMenu.setProgress(0.3f);

soundManager.loadMusic(new Sound[]{Sound.DEMOTRACK_1});

mainMenu.setProgress(0.4f);

levelManager.initialise(level);

mainMenu.setProgress(0.6f);

transformManager.initialise();

GameState.setGameState(GameState.RUNNING);

mainMenu.setProgress(1f);

mainMenu.getNifty().gotoScreen(“end”);

}

public void executionProgress(float progress){

mainMenu.setProgress(progress);

}

}

ProgressBar progressBar = new ProgressBar;



public void simpleInit() {

progressBar.executeCode();

}

[/java]



is there?



if not and i would to create is there any way to check what line of code(or just compiled fragment) is executing and max data to execute in method?

1 Like

ok, don’t had answer about it, but i created solution for Frame check execution here:



http://hub.jmonkeyengine.org/groups/user-code-projects/forum/topic/progressmanager-progressbar-facilitation/

your on quite a rampage today aren’t u :stuck_out_tongue:

agreed :smiley:



had many coffeine:



http://www.youtube.com/watch?v=YmCjMRAzCiE


:smiley:

1 Like