0
\$\begingroup\$

I'm currently working on a (trading) card game in XNA and I'm having some trouble with returning results from a popup and immediately using them.

I'm able to make a popup screen (see this tutorial) and get a return value from the Yes/No selection while preventing further updates to the "battle" game component, but I'd like to do this while maintaining my location within one update cycle of the game component Update method as I want the popup in question to happen only once: namely when a particular card is played.

The ideal solution would be a way to pause the Update of one game component, continue updating the rest of the game to get my input data from the popup, and then return to the same spot in the paused game component's Update with my new input data.

Any ideas?

EDIT: This method is an effect called from the game component Update method. As a similar effect could be called in the middle of a process (effect before/after an attack), preserving the location within the game component Update is important.

public void Cow(Card c)
    {
        bool temp = YesOrNo("Sacrifice Cow for 300 LP?");
        if (temp)
        {
            if (c.ownerP1) { lp1 = lp1 + 300; }
            else { lp2 = lp2 + 300; }

            Discard(c);
        }
    }

Also within the game component.

public bool YesOrNo(string message)
    {
        game.StartYesNoScreen(message);
        bool val = Convert.ToBoolean(game.yesNoScreen.result);
        return val;
    }

This is within the Game1 class itself. The Show method enables the activeScreen component and makes it visible.

public void StartYesNoScreen(string text)
    {
        activeScreen.Enabled = false;
        activeScreen = yesNoScreen;
        yesNoScreen.text = text;
        activeScreen.Show();
    }

The Game1 Update method.

protected override void Update(GameTime gameTime)
    {
        this.gameTime = gameTime;
        keyboardState = Keyboard.GetState();

        if (activeScreen == startScreen) { HandleStartScreen(); }
        else if (activeScreen == actionScreen) { HandleActionScreen(); }
        else if (activeScreen == quitScreen) { HandleQuitScreen(); }
        else if (activeScreen == yesNoScreen) { HandleYesNoScreen(); }

        base.Update(gameTime);
        oldKeyboardState = keyboardState;
    }

Another method in the Game1 class.

private void HandleYesNoScreen()
    {
        if (KeyPress(Keys.Enter))
        {
            if (quitScreen.SelectedIndex == 0)
            {
                activeScreen.Hide();
                activeScreen = actionScreen;
                activeScreen.Show();
                yesNoScreen.SelectedIndex = 0;
                yesNoScreen.result = 1;
            }
            else
            {
                activeScreen.Hide();
                activeScreen = actionScreen;
                activeScreen.Show();
                yesNoScreen.SelectedIndex = 0;
                yesNoScreen.result = 0;
            }
        }
    }
\$\endgroup\$
2
  • \$\begingroup\$ perhaps a boolean or an enum? where something like this would be your code: if (popupIsShowing == false) { Update(); } Therefore the game component would only update if there is no pop up. \$\endgroup\$ Aug 10, 2013 at 20:44
  • \$\begingroup\$ That would be fine for preventing more update calls, but the issue is not with stopping the game component from further updates until the popup is closed, but with halting the update the component is currently on until the popup is closed and then resuming it. I'm not even sure if that's possible. \$\endgroup\$
    – cablay
    Aug 10, 2013 at 20:53

2 Answers 2

1
\$\begingroup\$

Usually is done with a stack of scenes or gamestates...

when you push a popup on top of the stack it becomes the active component that get updates...

You can get a microsoft sample about game state management here http://xbox.create.msdn.com/en-US/education/catalog/sample/game_state_management

Or you can get it done by yourself:

 public abstract class GameState {
        protected  bool UpdateIfNotOnTop = false;
        protected  bool DrawIfNotOnTop = false;

        protected abstract void Update();
        protected abstract void Draw();


      public class GameStateManager  {

         public readonly static Instance = new GameStateManager();

         Stack<GameState> States = new Stack<GameState>();

         public void Push(GameState State) { States.Push(State); }
         public void Pop() { States.Pop(); }

         public void Update() {
              foreach (var state in States.ToArray())
              {
                   if (States.Peek() == state || state.UpdateIfNotOnTop)
                  {
                      state.Update();
                  }
              }                
         }

         public void Draw() {
              foreach (var state in States.ToArray())
              {
                   if (States.Peek() == state || state.DrawIfNotOnTop)
                  {
                      state.Draw();
                  }
              }                
         }
      }
  }
\$\endgroup\$
4
  • \$\begingroup\$ Looks promising. By calling it a stack it makes it sound like I could, but would I be able to stop a component Update call by pushing it onto the stack and then resume it where it was when I pop it off again? \$\endgroup\$
    – cablay
    Aug 11, 2013 at 0:17
  • \$\begingroup\$ If you want to use a popup, you push it on the stack, when the popup ends, you have to pop it, returning to the normal update loop of your game \$\endgroup\$
    – Blau
    Aug 11, 2013 at 10:03
  • \$\begingroup\$ I've gone through the sample and unfortunately it doesn't look like it has the functionality I was hoping for. After going to the pause screen it does not resume its place in the GameplayScreen Update method but rather starts it over again after GameplayScreen is once again the active screen. I still cannot find a way to reenter an Update method where it was stopped, so I think I may have to change how I do my update method to where I do not have to reenter it where it was stopped. \$\endgroup\$
    – cablay
    Aug 13, 2013 at 16:05
  • \$\begingroup\$ I don't remember how gamestatement sample was done... but I'm almost sure what you want can be done with it... and I'm sure that using something similar to my code is feasible too... \$\endgroup\$
    – Blau
    Aug 13, 2013 at 16:10
0
\$\begingroup\$

Perhaps you can disable said component(s) (set enabled to false) until you have processed the results, and then re-enable it

\$\endgroup\$
4
  • \$\begingroup\$ Unfortunately that's already done when the popup is shown. I'll try to add some code to clarify my issue. \$\endgroup\$
    – cablay
    Aug 10, 2013 at 21:51
  • \$\begingroup\$ You could use events. (Fire an event when a result is returned, and just handle that, not messing with the components themselves) \$\endgroup\$
    – CobaltHex
    Aug 10, 2013 at 21:52
  • \$\begingroup\$ I'd thought about trying to use an event, but wouldn't I run into the same problem of the game component update needing to be finished before I can do things with my popup window? \$\endgroup\$
    – cablay
    Aug 11, 2013 at 0:09
  • \$\begingroup\$ See blau's comment \$\endgroup\$
    – CobaltHex
    Aug 11, 2013 at 3:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .