2
\$\begingroup\$

I used the code from this - http://www.xnadevelopment.com/tutorials/thestateofthings/thestateofthings.shtml (The second method using enumerations)

I modified it to add a 3rd screen for gameplay and it functioned like the previous screen. The issue is that since the Controller Detect Screen and Title Screen both use the A button to advance. Because of this, it advances through both at the same time, going straight to the gameplay screen. I changed the code (as seen below) so that the Title Screen uses a different button. However, I want to have it so it uses the same button, but not advance at the same time.

Hopefully I explained it correctly.

        private void UpdateControllerDetectScreen()
    {

        //Poll all the gamepads (and the keyboard) to check to see

        //which controller will be the player one controller

        for (int aPlayer = 0; aPlayer < 4; aPlayer++)
        {

            if (GamePad.GetState((PlayerIndex)aPlayer).Buttons.A == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.A) == true)
            {

                mPlayerOne = (PlayerIndex)aPlayer;

                mCurrentScreen = ScreenState.Title;

                return;

            }

        }

    }

    private void UpdateTitleScreen()
    {

        //Move back to the Controller detect screen if the player moves

        //back (using B) from the Title screen (this is typical game behavior

        //and is used to switch to a new player one controller)

        if (GamePad.GetState(mPlayerOne).Buttons.B == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.B) == true)
        {

            mCurrentScreen = ScreenState.ControllerDetect;

            return;

        }

        if (GamePad.GetState((PlayerIndex)mPlayerOne).Buttons.A == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.C) == true)
        {



            mCurrentScreen = ScreenState.GamePlay;

            return;

        }

    }

    private void UpdateGamePlayScreen()
    {

        //Move back to the Controller detect screen if the player moves

        //back (using B) from the Title screen (this is typical game behavior

        //and is used to switch to a new player one controller)

        if (GamePad.GetState(mPlayerOne).Buttons.B == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.B) == true)
        {

            mCurrentScreen = ScreenState.Title;

            return;

        }





    }
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

You need to distinguish between a single key press (or button) from the key being held down.

This can be accomplished by adding an extra check to your if statement, so that besides checking if the button (or key) is currently down you also need to check if that same button (or key) was up on the previous frame.

If both are true, then we're dealing with with the first frame of a key press, and anything you put inside will only be triggered once. In order for it to be triggered again, you would need to release the button and press it again.

I've already written twice about this problem:

But transcribing the most essential bits, the technique can be summarized as this:

private KeyboardState _currentKeyboardState;
private KeyboardState _previousKeyboardState;

public void Update(GameTime elapsed)
{
    // Before handling input
    _currentKeyboardState = Keyboard.GetState();

    if(_currentKeyboardState.IsKeyDown(Keys.A) &&
       _previousKeyboardState.IsKeyUp(Keys.A))
    {
        // Change screen here
    }

    _previousKeyboardState = _currentKeyboardState;
}

Adapt this to your needs, i.e. store the gamepad state and check for it too, possibly encapsulate everything in a class (for example, the first question I linked above has an answer with an implementation that seems pretty complete, while the second question has a minimalistic implementation).

\$\endgroup\$
2
  • 1
    \$\begingroup\$ +1 For this reason you normally have an object of some kind that helps you work with the keyboard. I have a KeyboardDevice which has these methods: IsKeyDown, IsKeyUp, WasKeyPressed, WasKeyReleased - all of which take a key and return whether what I'm asking it is happening with that key. \$\endgroup\$ Commented Apr 26, 2012 at 1:05
  • \$\begingroup\$ Thanks. Your Global Keyboard States example worked, though there was a grammar error where _currentKeyboardState; was spelled as _currentKeybordState; \$\endgroup\$
    – Slateboard
    Commented Apr 26, 2012 at 2:35

You must log in to answer this question.

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