I am trying to use the AppStates to whip up a menu and a small game scene and being able to switch between them. I created a BaseGameAction that implements AppState.
BaseGameState
[java]
package sector.soda.states;
import com.jme3.app.Application;
import com.jme3.app.state.AppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.renderer.RenderManager;
/**
*
@author cheesecake
*/
public class BaseGameState implements AppState {
protected boolean initialized = false;
private boolean active = true;
public void initialize(AppStateManager stateManager, Application app) {
initialized = true;
}
public boolean isInitialized() {
return initialized;
}
public void setActive(boolean active) {
this.active = active;
}
public boolean isActive() {
return active;
}
public void stateAttached(AppStateManager stateManager) {
}
public void stateDetached(AppStateManager stateManager) {
cleanup();
}
public void render(RenderManager rm) {
}
public void postRender() {
}
public void cleanup() {
initialized = false;
}
public void update(float tpf) {
}
}
[/java]
I got a GameState that extends the BaseGameState. It sets up a small scene attaching the Spatial to the rootNode from Main
[java]
package sector.soda.states;
import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import java.util.logging.Level;
import sector.soda.Main;
import sector.soda.util.MyLogger;
/**
*
@author cheesecake
*/
public class GameState extends BaseGameState {
public AppStateManager mySm;
public Application myApp;
private boolean gamePaused = false;
private static MyLogger logger = Main.log;
DirectionalLight sun;
public GameState() {
logger.log(Level.INFO, "GameState constructor");
}
@Override
public void initialize(AppStateManager stateManager, Application app) {
private AnalogListener analogListener = new AnalogListener() {
public void onAnalog(String name, float value, float tpf) {
if (!gamePaused) {
if (name.equals("Right")) {
}
if (name.equals("Left")) {
}
}
}
};
}
[/java]
I also have a working MenuState which displays a simple Nifty GUI. I am currently trying to just load the GameState first to see if something will show up. Is the way I am attaching it to the rootNode like this ok ? Should I give every state its own Node for rendering and how would I go about attaching that to the rootNode and getting something to display ?
Or is it better to try and use the GameState I found on the svn:
Seems to only work if I pass along the first rootNode to the GameState.
Main
[java]
package sector.soda;
import com.jme3.app.SimpleApplication;
import com.jme3.renderer.RenderManager;
import sector.soda.states.GameState;
import sector.soda.util.MyLogger;
/**
@author cheesecake
*/
public class Main extends SimpleApplication {
public static final MyLogger log = new MyLogger(“Sector_Soda.log”);
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
GameState gameState = new GameState(rootNode);
stateManager.attach(gameState);
}
@Override
public void simpleUpdate(float tpf) {
}
@Override
public void simpleRender(RenderManager rm) {
}
}
[/java]
The getRootNode() that is used in GameState is probably not the same “Root Node” that is needed. This is the getRootNode() from the BaseGameState that extends SimpleApplication;
[java]
getRootNode().attachChild(alien);
[/java]
It just seems a bit ugly passing along the rootNode to all states that need to draw something on the screen.
You should only have one Application/SimpleApplication based class. Only the real one will have real information. Your subclasses will just contain nothing of use… besides, app states are given a reference to the main application instance when they are initialized.
Why did you feel the need to have your game state extend application?
pspeed said:
You should only have one Application/SimpleApplication based class. Only the real one will have real information. Your subclasses will just contain nothing of use... besides, app states are given a reference to the main application instance when they are initialized.
Why did you feel the need to have your game state extend application?
At the moment only Main extends Application/SimpleApplication and the states extend BaseGameState which implements AppState. At first I tried that to see if I could get to the rootNode that way.
My question now would be. How do I get access to the rootNode to load scene stuff in a state ?
[java]
Spatial alien = myApp.getAssetManager().loadModel("Models/Alien/Skin_Sym_Low_6.mesh.j3o");
alien.setLocalTranslation(0.0f, 0.0f, -2.0f);
// to which node do I attach the alien ?
[/java]
Is there a way to get it from the stateManager or Application app ? Or maybe I should not be (mis) using GameState this way to load scenes.
I updated the OP. For now I use the Main.node which gets set when starting the game.
Yeah, you look like you are using them right to me. I think there is a JME bug maybe. Something that isn’t detecting the “dirtiness” of root node unless you change it during update().
…but I’m only guessing and have not looked at any of that code recently.
The strange thing is that I can output player.getName() in the update() method but I have to do the whole player “initialization” inside update() to get the translation to work.
And how to get the speed value in a game state? is it always set to 1.0?
Actually I’m using SimpleApplication :). But you’re right, I’ll probably put my game objects in global variables and initialize them in simpleInitApp().