I’m running the code from the playerControl, when the player’s health is below zero.
After detaching the appstate it seems that one or more controls are still mid update loop and execute it to the end… By adding this line of code I don’t get an exception in the control anymore:
[java]if(app.getStateManager().getState(GameRunningState.class) == null) return;[/java]
But I suddenly get a NPE at another AppState:
[java]
getPhysicsManager().clear(); //cleanup of gamerunningstate
pM = null;
app.getStateManager().detach(app.getStateManager().getState(MusicState.class));
System.out.print("GameRunningState: ");
System.out.println(app.getStateManager().getState(ViewPortState.class) == null);
app.getStateManager().detach(app.getStateManager().getState(ColtState.class));
app.getStateManager().detach(app.getStateManager().getState(ViewPortState.class));
app.getGuiNode().detachAllChildren();
app.getRootNode().detachAllChildren();
[/java]
As you see, I detach the coltState and then detach the ViewPortState. But I get a NPE in ColtState because the ViewPortState is null. Here there is the cleanup of ColtState:
[java]uper.cleanup();
System.out.print("ColtState7: ");
System.out.println(app.getStateManager().getState(ViewPortState.class) == null);
app.getStateManager().getState(ViewPortState.class).getRoot().detachChild(smoke); //NPE
app.getStateManager().getState(ViewPortState.class).getRoot().detachChild(flame);
app.getInputManager().deleteMapping(“Shoot”);
app.getInputManager().removeListener(actionListener);
app.getStateManager().getState(ViewPortState.class).getRoot().detachChild(sound);
app.getStateManager().getState(ViewPortState.class).getRoot().detachChild(colt);[/java]
That’s the stacktrace:
[java]java.lang.NullPointerException
at net.softwarepage.fearkill.ColtState.cleanup(ColtState.java:173)
at com.jme3.app.state.AppStateManager.terminatePending(AppStateManager.java:261)
at com.jme3.app.state.AppStateManager.update(AppStateManager.java:278)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:239)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)
at java.lang.Thread.run(Thread.java:744) [/java]
The output is: RunningState: false; ColtState: true
So ViewPortState suddenly becomes null!?
And if I keep the ColtState attached and try just to detach the ViewportState, I get the following exception:
[java]
java.lang.IllegalStateException: Scene graph is not properly updated for rendering.
State was changed after rootNode.updateGeometricState() call.
Make sure you do not modify the scene from another thread!
Problem spatial name: Viewport Root[/java]
where Viewport Root is the Root node of the ViewPort of the ViewPortState which code follows:
[java]package net.softwarepage.fearkill;
import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.Spatial.CullHint;
public class ViewPortState extends AbstractAppState {
private Camera cam;
private ViewPort view;
private Node root;
private Spatial currentGun;
private Application app;
public ViewPortState() {
root = new Node("root");
}
public Node getRoot() {
return root;
}
public Camera getCamera() {
return cam;
}
public void setCurrentGun(Spatial s) {
currentGun = s;
}
public Spatial getCurrentGun() {
return currentGun;
}
@Override
public void initialize(AppStateManager stateManager, Application application) {
super.initialize(stateManager, application);
app = application;
root = new Node("Viewport Root");
root.setCullHint(CullHint.Never);
cam = app.getCamera().clone();
cam.setViewPort(0.0f, 1.0f, 0.0f, 1f);
view = app.getRenderManager().createMainView("GunViewPort", cam);
getView().setEnabled(true);
getView().setClearFlags(false, true, false);
getView().attachScene(root);
initFlashlight();
root.updateLogicalState(1);
root.updateGeometricState();
}
private void initFlashlight() {
Spatial flashlight = app.getAssetManager().loadModel("Models/flashlight.j3o");
flashlight.setLocalTranslation(-5.5f, -5.8f, 0f);
flashlight.rotate(20 * FastMath.DEG_TO_RAD, -20 * FastMath.DEG_TO_RAD, 0);
app.getStateManager().getState(ViewPortState.class).getRoot().attachChild(flashlight);
DirectionalLight sun = new DirectionalLight();
sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());
sun.setColor(ColorRGBA.White);
flashlight.addLight(sun);
}
@Override
public void render(RenderManager rm) {
root.updateGeometricState();
}
@Override
public void update(float tpf) {
root.updateLogicalState(tpf);
}
@Override
public void cleanup() {
root.detachAllChildren();
}
/**
* @return the view
*/
public ViewPort getView() {
return view;
}
}[/java]
I just don’t get anything anymore
Why is the ViewPortState suddenly null when I detach the ColtState? And what does that other exception mean?