Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

The ingame menu opens when the player presses Escape during the main game. If the player presses Y in the ingame menu, the game switches to the main menu. Up to here, everything works. But: On the other hand, if the player presses N in the ingame menu, the game should switch back to the main game(should resume the main game). But that doesn't work. The game just rests in the ingame menu if the player presses N. I set a breakpoint in this line of the Ingamemenu class:

KeyboardState kbState = Keyboard.GetState();

CurrentSate/currentGameState and LastState/lastGameState have the same state: IngamemenuState. But LastState/lastGameState should not have the same state than CurrentSate/currentGameState. What is wrong? Why is the ingame menu not working correctly?

public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    IState lastState, currentState;

    public enum GameStates
    {
        IntroState = 0,
        MenuState = 1,
        MaingameState = 2,
        IngamemenuState = 3
    }

    public void ChangeGameState(GameStates newState)
    {
        lastGameState = currentGameState;
        lastState = currentState;
        switch (newState)
        {
            case GameStates.IntroState:
                currentState = new Intro(this);
                currentGameState = GameStates.IntroState;
                break;
            case GameStates.MenuState:
                currentState = new Menu(this);
                currentGameState = GameStates.MenuState;
                break;
            case GameStates.MaingameState:
                  currentState = new Maingame(this);
                  currentGameState = GameStates.MaingameState;
                break;
            case GameStates.IngamemenuState:
                currentState = new Ingamemenu(this);
                currentGameState = GameStates.IngamemenuState;
                break;
        }
        currentState.Load(Content);
    }

    public void ChangeCurrentToLastGameState()
    {
        currentGameState = lastGameState;
        currentState = lastState;
    }

    public GameStates CurrentState
    {
        get { return currentGameState; }
        set { currentGameState = value; }
    }

    public GameStates LastState
    {
        get { return lastGameState; }
        set { lastGameState = value; }
    }

    private GameStates currentGameState = GameStates.IntroState;
    private GameStates lastGameState;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    protected override void Initialize()
    {
        ChangeGameState(GameStates.IntroState);
        base.Initialize();
    }

    protected override void LoadContent()
    {       
        spriteBatch = new SpriteBatch(GraphicsDevice);
        currentState.Load(Content);
    }

    protected override void Update(GameTime gameTime)
    {
        currentState.Update(gameTime);
        if ((lastGameState == GameStates.MaingameState) && (currentGameState == GameStates.IngamemenuState))
        {
            lastState.Update(gameTime);
        }
        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
        if ((lastGameState == GameStates.MaingameState) && (currentGameState == GameStates.IngamemenuState))
        {
          lastState.Render(spriteBatch);
        }
        currentState.Render(spriteBatch);
        spriteBatch.End();

        base.Draw(gameTime);
    }
}

public interface IState
    {
        void Load(ContentManager content);
        void Update(GameTime gametime);
        void Render(SpriteBatch batch);
    }


public class Intro : IState
{
    Texture2D Titelbildschirm;
    private Game1 game1;       

    public Intro(Game1 game)
    {
        game1 = game;
    }

    public void Load(ContentManager content)
    {
       Titelbildschirm = content.Load<Texture2D>("gruft");
    }

    public void Update(GameTime gametime)
    {
        KeyboardState kbState = Keyboard.GetState();
        if (kbState.IsKeyDown(Keys.Space))
            game1.ChangeGameState(Game1.GameStates.MenuState);
    }

    public void Render(SpriteBatch batch)
    {
        batch.Draw(Titelbildschirm, new Rectangle(0, 0, 1280, 720), Color.White);
    }
}


public class Menu:IState
{
Texture2D Choosescreen;
private Game1 game1;

    public Menu(Game1 game)
    {
        game1 = game;
    }

public void Load(ContentManager content)
{
    Choosescreen = content.Load<Texture2D>("menubild");
}

public void Update(GameTime gametime)
{
    KeyboardState kbState = Keyboard.GetState();
    if (kbState.IsKeyDown(Keys.Enter))
        game1.ChangeGameState(Game1.GameStates.MaingameState);
    if (kbState.IsKeyDown(Keys.Escape))
        game1.Exit();
}

public void Render(SpriteBatch batch)
{
    batch.Draw(Choosescreen, new Rectangle(0, 0, 1280, 720), Color.White);
}
}

public class Maingame : IState
{
    Texture2D Spielbildschirm, axe;
    Vector2 position = new Vector2(100,100);

    private Game1 game1;

    public Maingame(Game1 game)
    {
        game1 = game;
    }

    public void Load(ContentManager content)
    {
        Spielbildschirm = content.Load<Texture2D>("hauszombie");
        axe = content.Load<Texture2D>("axxx");
    }

    public void Update(GameTime gametime)
    {
          KeyboardState keyboardState = Keyboard.GetState();
          float delta = (float)gametime.ElapsedGameTime.TotalSeconds;
          position.X += 5 * delta;
          position.Y += 3 * delta;

          if (keyboardState.IsKeyDown(Keys.Escape))
            game1.ChangeGameState(Game1.GameStates.IngamemenuState);        
    }

    public void Render(SpriteBatch batch)
    {
        batch.Draw(Spielbildschirm, new Rectangle(0, 0, 1280, 720), Color.White);
        batch.Draw(axe, position, Color.White);
    }
}

public class Ingamemenu : IState
{
    Texture2D Quitscreen;
    private Game1 game1;

    public Ingamemenu(Game1 game)
    {
        game1 = game;
    }

    public void Load(ContentManager content)
    {
        Quitscreen = content.Load<Texture2D>("quit");
    }

    public void Update(GameTime gametime)
    {
        KeyboardState kbState = Keyboard.GetState();
        if (kbState.IsKeyDown(Keys.Y))
           game1.ChangeGameState(Game1.GameStates.MenuState);
        if (kbState.IsKeyDown(Keys.N))
          game1.ChangeCurrentToLastGameState();
    }

    public void Render(SpriteBatch batch)
    {
        batch.Draw(Quitscreen, new Rectangle(200, 200, 200, 200), Color.White);
    }
}
share|improve this question
add comment

closed as too localized by Byte56, Trevor Powell, bummzack, Josh Petrie, Nick Wiggill Jan 2 '13 at 12:34

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

1 Answer

up vote 1 down vote accepted

Well, I have a guess.

You need to hit ESC faster :)

You have this code in your update:

if ((lastGameState == GameStates.MaingameState) &&
   (currentGameState == GameStates.IngamemenuState))
{
    lastState.Update(gameTime);
}

So that means when you're in IngamemenuState your game continues to update the last state MaingameState.

And in your MaingameState update you have this code:

if (keyboardState.IsKeyDown(Keys.Escape))
    game1.ChangeGameState(Game1.GameStates.IngamemenuState);

So unless you're super fast on hitting that ESC key, you're going to trigger this line twice (just twice because after lastGameState is updated again, MaingameState no longer gets updated):

game1.ChangeGameState(Game1.GameStates.IngamemenuState);

So, you're likely changing multiple times into IngamemenuState, which makes your last state and previous states both IngamemenuState.

Try setting a printout in your ChangeGameState function showing the previous and next states. I'm guessing you'll see two printouts

MaingameState -> IngamemenuState

and

IngamemenuState -> IngamemenuState

Try changing this:

 if (keyboardState.IsKeyDown(Keys.Escape))
     game1.ChangeGameState(Game1.GameStates.IngamemenuState); 

to this:

 if (keyboardState.IsKeyDown(Keys.Escape) && game1.currentState != IngamemenuState)
     game1.ChangeGameState(Game1.GameStates.IngamemenuState); 

Or something like that. Basically, you don't want to change into the menu, if you're already in the menu.

Better yet, just do the check inside your ChangeGameState function:

 if(newState == currentGameState)
     return;

You should also be checking all your inputs so you don't duplicate commands like this.

share|improve this answer
    
I set a breakpoint in each of these two lines in game1 class: currentGameState = lastGameState; currentState = lastState; CurrentSate/currentGameState and LastState/lastGameState always have the same state: IngamemenuState. What should I change in the game1 class? I'm not sure how to change the update method of game1. –  Johnny Dec 19 '12 at 23:57
    
Yes, they would be at that point. See my edit. –  Byte56 Dec 20 '12 at 0:05
    
I just changed this line like you said and the ingame menu works now. if ((keyboardState.IsKeyDown(Keys.Escape)) && (game1.CurrentState != Game1.GameStates.IngamemenuState)) game1.ChangeGameState(Game1.GameStates.IngamemenuState); But I did not understand how to change the ChangeGameState function. How should I change the ChangeGameState function to improve the code? –  Johnny Dec 20 '12 at 12:02
    
Johnny, Not much learning if I tell you how to change everything. I've given you all the information you need to fix it. This site isn't about people telling you how to write your code, we tell you what's wrong or how to fix it and you implement the changes. Good luck! Glad it's working. –  Byte56 Dec 20 '12 at 15:43
    
I don't understand what this line means. if(newState == currentGameState) return; What is return? Why do you use return? –  Johnny Dec 20 '12 at 16:19
show 3 more comments

Not the answer you're looking for? Browse other questions tagged or ask your own question.