[SOLVED] New to jME, having trouble with GameState.update()

Hello good people,



I'm new to jME and much of it's conceptual underpinnings (3D, physics, etc.);  not new to Java, though.



I'm having difficulty, and it seems to be related to building a GameState tree properly using StandardGame.



From my log messages, I know that:

  - I am passing my GameState instances to GameStateManager.attachChild()

  - I am calling setActive(true) on my GameState instances

  - The update() and render() methods of my GameState instances are not being called by jME



I've got a solid black screen.



I'm guessing there's something fundamental I'm overlooking.



Code sample:



    public static void main(final String[] args) {
       
        // Instance Members...
        final Log log = LogFactory.getLog(Main.class);

        // Create & load the app context...
        final ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(CONTEXT_LOCATION_PATTERN);
                       
        final GameState activate = (GameState) ctx.getBean(ACTIVATE_GAME_STATE_BEAN);
        try {

            final GameTaskQueueManager gameTaskQueue = GameTaskQueueManager.getManager();

            // Attach game states to the manager...
            final List<GameState> gameStates = (List<GameState>) ctx.getBean(GAME_STATES_BEAN);
            gameTaskQueue.update(new Callable() {
                public Object call() throws Exception {
                    for (final GameState s : gameStates) {
                        if (log.isDebugEnabled()) {
                            log.debug("Registering GameState with GameStateManager:  " + s.getName());
                        }
                        GameStateManager.getInstance().attachChild(s);
                    }
                    return null;
                }
            }).get();

            // Activate the specified state...
            gameTaskQueue.update(new Callable() {
                public Object call() throws Exception {
                    if (log.isDebugEnabled()) {
                        log.debug("Activating GameState:  " + activate.getName());
                    }
                    GameStateManager.getInstance().activateChildNamed(activate.getName());
                    return null;
                }
            }).get();
           
        } catch (Throwable t) {
            String msg = "Failed to activate the game state:  " + activate.getName();
            throw new RuntimeException(msg, t);
        }
       
    }



Thanks for any suggestions!

You need to have a running StandardGame instace, which renders your Gamestates.



        StandardGame game = new StandardGame("TestGame");       // Create our game
        game.start();   // Start the game thread

Core-Dump said:

You need to have a running StandardGame instace, which renders your Gamestates.


Sure.

I do have a nice 1024x768 black window that pops up when I start my app, from which I'm inferring that the StandardGame instance is starting properly.

I'm invoking StandardGame.start() in the application context:


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">

    <bean id="gameInstance" class="com.jmex.game.StandardGame" init-method="start">
        <constructor-arg value="Nimue MMO"/>
        <constructor-arg value="GRAPHICAL"/>
        <constructor-arg ref="gameSettings"/>
    </bean>

    <bean id="gameSettings" class="com.jme.system.PropertiesGameSettings" init-method="load">
        <constructor-arg value="config/userSettings.properties"/>
        <constructor-arg value="/defaultSettings.properties"/>
    </bean>

</beans>

The problem appears to be with my ContainerState class:



public final class ContainerState<G extends GameState> extends BasicGameStateNode<G> {
   
    // Instance Members...
    private final Log log = LogFactory.getLog(getClass());
       
    /*
     * Public API.
     */
   
    public ContainerState(String name) {
        super(name);
    }
   
    @Override
    public void setActive(boolean active) {
               
        if (active) {
            if (log.isDebugEnabled()) {
                log.debug("Activating:  " + this.getName());
            }
            this.activateAllChildren();
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Deactivating:  " + this.getName());
            }
            this.deactivateAllChildren();
        }
       
    }
   
    @Required
    public void setChildStates(List<G> childStates) {

        if (log.isDebugEnabled()) {
            StringBuilder bld = new StringBuilder();
            bld.append("Attaching childStates: ");
            for (GameState gs : childStates) {
                bld.append(" ").append(gs.getName()).append(",");
            }
            bld.setLength(bld.length() - 1);
            log.debug(bld.toString());
        }

        for (G gs : childStates) {
            this.attachChild(gs);
        }
       
    }
   
}



When I add my "real" GameState instances to an instance of this class and attach it to the GameStateManager, I get the big black screen and my update() and render() methods never get called.

When I add my "real" GameState instances directly to the GameStateManager, everything works as expected.

doh!



I guess it's a good idea to call…


super.setActive(active);



if you're going to override GameState.setActive().

But that begs the question:  does it make sense to have BasicGameStateNode.setActive() call setActive() on each of it's children?

As someone new to the API, that was the behavior I was expecting.  I only got into the business of overriding setActive() in a custom subclass because I discovered this behavior wasn't happening.

But as I said -- I'm new to the API.  Is there another concrete GameState container I should be looking at or using?