Main menu gamestate

Is it possible to have a main menu to choose different game to start by extends SimpleGame?



When user press ESC button, return back to main menu.



In main menu user can choose another game to start again.



I saw an open source game extends BasicGameState.



Is that best / easiest way of doing it?



http://www.koders.com/java/fid20E4EDBA086CF3EC326EE0290C66046BFD04CD6F.aspx?s=MainMenuGameState#L2

Inorder to escape to main menu and choose another game, I must use some kind of GameState like extending BasicGameState correct?



Because most of the game i write so far is extending SimpleGame, how can I convert all the SimpleGame and convert it to extends BasicGameState / GameState?

It is very simple to convert your code to BaseGame… Just take a peek at the source of SimpleGame and cut&paste pieces of the code that you need to keep, and call your game StmarspGame or something.

I not meaning extending BaseGame, but I mean extends GameState like follows:



How can I convert all the game extends SimpleGame to extends GameState?



Thanks again!



http://www.koders.com/java/fid1876CEFBC4B4D0A32D01B5826CDE0A8940939F23.aspx?s=monkeymahjongg+main#L25




package jmetest.monkeymahjongg;

import com.jme.input.MouseInput;
import com.jme.renderer.ColorRGBA;
import com.jme.system.GameSettings;
import com.jme.system.PreferencesGameSettings;
import com.jme.util.GameTaskQueueManager;
import com.jmex.game.StandardGame;
import com.jmex.game.state.GameState;
import java.util.prefs.Preferences;
import jmetest.monkeymahjongg.menu.BackgroundGameState;
import com.jmex.game.state.GameStateManager;
import java.lang.reflect.Constructor;
import java.util.concurrent.Callable;
import java.util.logging.Logger;
import java.util.prefs.BackingStoreException;
import jmetest.monkeymahjongg.game.CameraGameState;
import jmetest.monkeymahjongg.game.MahGameState;
import jmetest.monkeymahjongg.menu.swingui.MainMenuGameState;
import jmetest.monkeymahjongg.menu.swingui.SettingsMenuGameState;

/**
 *
 * @author Pirx
 */
public class Main  {

    private static Preferences preferences;
    private static GameSettings gameSettings;
    private static StandardGame standardGame;

    private static GameState backgroundGameState;
    private static GameState mainMenuGameState;
    private static GameState settingsMenuGameState;
    private static GameState levelMenuGameState;
    private static GameState mahjonggGameState;
    private static CameraGameState cameraGameState;

    private static String menuPackage;
   
    private static String layoutName = "standard";

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        menuPackage = (args.length == 0) ? "swingui" : args[0];

        preferences = Preferences.userNodeForPackage(Main.class);

        gameSettings = new PreferencesGameSettings(preferences);

        standardGame = new StandardGame("Monkey Mahjongg", StandardGame.GameType.GRAPHICAL, gameSettings);
        standardGame.setBackgroundColor(ColorRGBA.darkGray);
        standardGame.start();

        backgroundGameState = new BackgroundGameState("jmetest/monkeymahjongg/images/Monkey.jpg");
        GameStateManager.getInstance().attachChild(backgroundGameState);
        backgroundGameState.setActive(true);
       
        cameraGameState = new CameraGameState();
        GameStateManager.getInstance().attachChild(cameraGameState);
        cameraGameState.setActive(true);
        cameraGameState.setFixed();
       
        mahjonggGameState = new MahGameState("jmetest/monkeymahjongg/images/Monkey.jpg");
        GameStateManager.getInstance().attachChild(mahjonggGameState);

        try {
            mainMenuGameState = (GameState) Class.forName(
                "jmetest.monkeymahjongg.menu." + menuPackage + ".MainMenuGameState"
            ).newInstance();
           
            GameStateManager.getInstance().attachChild(mainMenuGameState);
            mainMenuGameState.setActive(true);
           
            Constructor settingsConstructor = Class.forName(
            "jmetest.monkeymahjongg.menu." + menuPackage + ".SettingsMenuGameState"
            ).getConstructor(GameSettings.class);  
           
           
            settingsMenuGameState = (GameState) settingsConstructor.newInstance(gameSettings);
            GameStateManager.getInstance().attachChild(settingsMenuGameState);
           
        } catch (Exception ex) {
            ex.printStackTrace();
            System.exit(-1);
        }

        setCursorVisible(true);
    }

    private static void setCursorVisible(final boolean visible) {
        GameTaskQueueManager.getManager().update(new Callable<Object>() {

            public Object call() throws Exception {
                MouseInput.get().setCursorVisible(visible);
                return null;
            }
        });
    }

    public static void selectSettingsMenu() {
        mainMenuGameState.setActive(false);
        settingsMenuGameState.setActive(true);
    }

    public static void selectMainMenu() {
        settingsMenuGameState.setActive(false);
        backgroundGameState.setActive(true);
        mainMenuGameState.setActive(true);
    }

    public static void startLevel() {
        mainMenuGameState.setActive(false);
        backgroundGameState.setActive(false);
        mahjonggGameState.setActive(true);
        cameraGameState.setMoveable();
    }
   
    public static void stopLevel() {
        mainMenuGameState.setActive(true);
        backgroundGameState.setActive(true);
        mahjonggGameState.setActive(false);
        cameraGameState.setFixed();
    }
   
   
    public static void setLayoutName(String layoutName) {
        Main.layoutName = layoutName;
    }
   
//    public static Level getLevel() {
//        return new Level("level/" + layoutName + ".xml");
//    }

    public static void exit() {
        standardGame.shutdown();
    }
   
        public static void savePreferences() {
        try {
            preferences.flush();
        } catch (BackingStoreException ex) {
            //Logger.getLogger("global").log(Level.SEVERE, null, ex);
        }
    }
   
    public static void changeResolution() {
        //standardGame.recreateGraphicalContext();
    }
}

DebugGameState is meant to be the closest to a direct conversion from SimpleGame to a GameState.

Why only DebugGameState?



It seems BasicGameState / GameState is no difference from DebugGameState if you look at method definition?



Node getRootNode() 

void render(float tpf)

void update(float tpf)



How can I convert the

simpleInitGame()

simpleUpdate()

simpleRender()



into above methods?



Thanks again!

easy :slight_smile:



SimpleGame                GameState


simpleInitGame()    -> Constructor or setActive()
simpleUpdate()      -> update()
simpleRender()      -> render()

My point was that DebugGameState provides the majority of the "extras" that SimpleGame provides for you where BasicGameState is meant to be a nearly empty shell.

If I want to have a main menu, is that true I must use GameState instead of just extends SimpleGame???

Must is such a strong word  ;)… GameStates will help you achieve the functionality of a menu, in-game or otherwise. It will also make it easy to modularize your scene into discrete zones, and much more. But of course you can implement everything from SimpleGame, it is just a matter of style.

What's the difference between GameState and SimpleGame?



Is that each GameState is crossponding to one SimpleGame?



So that I can switch between different SimpleGame using GameState?



and GameState will store the last State of the SimpleGame and switch to another SimpleGame screen?



Later, when I come back to pervious SimpleGame screen, I will have the same state or reset to init State?



and GameState is managed by GameManager object?

You can't really compare a GameState and  SimpleGame.

A GameState is basically smiply a wrapper for a rootNode, which gets rendered by the GameStateManager in StandardGames update() method.



Maybe something like TestChooser is more what you look for.

In TestChosser you can select a Test (which usually extends a SimpleGame) and start it.

To elaborate a little:



GameStates are attached to a manager, and you can individually enable/disable them. Maybe the state in the name is misleading since they don't represent a persistent state of the game. They act as any other node in the scene-graph.



What is so cool about them, is that you can attach update/render code to them that will be executed automatically by the manager when they are enabled. In this sense is like having a SimpleGame inside them… The difference is that the SimpleGame is much more than just the scene and code, it is also the window, the renderer, the input system, etc. All of those things are not contained in states, they are simply shared among them.



Hope this helps.

duenez said:

The difference is that the SimpleGame is much more than just the scene and code, it is also the window, the renderer, the input system, etc. All of those things are not contained in states, they are simply shared among them.


Thank you very much for the detail explainations:

Yeah, I also notice SimpleGame has some util already initialized like
1) rootNode
2) fpsNode
3) display
4) timer
5) cam
6) input

where GameState don't have the above fields

So my problem when converting individual SimpleGame to each GameState is how to deal with above fields and convert to GameState

Any good idea if a Game extends SimpleGame that has above defined like: rootNode, input, cam ...etc?

DebugGameState is as close as you will get to SimpleGame functionality.