4
\$\begingroup\$

I'm making a pong game, and my paddles no longer continue to move after holding down the left thumbstick or dpad down. It simply moves once with each press. I think it is because I'm not checking for a LastKeyPressed anymore now that I've begun to use a new input class, which uses arrays to check for which controller is being uses, and that's not what I was using before.

I've got to store the previous state, but I'm not sure of how to o that with these arrays.

// From my input class:

  public Input()
    {
        // Get input state
        CurrentKeyboardState = new KeyboardState[MaxInputs];
        CurrentGamePadState = new GamePadState[MaxInputs];

        // Preserving last states to check for isKeyUp events
        LastKeyboardState = new KeyboardState[MaxInputs];
        LastGamePadState = new GamePadState[MaxInputs];
}

    /// <summary>
    /// Helper for checking if a button was newly pressed during this update.
    /// The controllingPlayer parameter specifies which player to read input for.
    /// If this is null, it will accept input from any player. When a button press
    /// is detected, the output playerIndex reports which player pressed it.
    /// </summary>
    public bool IsNewButtonPress(Buttons button, PlayerIndex? controllingPlayer, out PlayerIndex playerIndex)
    {
        if (controllingPlayer.HasValue)
        {
            // Read input from the specified player.
            playerIndex = controllingPlayer.Value;

            var i = (int)playerIndex;

            return CurrentGamePadState[i].IsButtonDown(button) && LastGamePadState[i].IsButtonUp(button);
        }
        else
        {
            // Accept input from any player.
            return IsNewButtonPress(button, PlayerIndex.One, out playerIndex)
                    || IsNewButtonPress(button, PlayerIndex.Two, out playerIndex)
                    || IsNewButtonPress(button, PlayerIndex.Three, out playerIndex)
                    || IsNewButtonPress(button, PlayerIndex.Four, out playerIndex);
        }
    }



    // Tells the left paddle to move down
    public bool LeftDown(PlayerIndex? controllingPlayer)
    {
        PlayerIndex playerIndex;

        return IsNewKeyPress(Keys.Down, controllingPlayer, out playerIndex)
               || IsNewButtonPress(Buttons.DPadDown, controllingPlayer, out playerIndex)
               || IsNewButtonPress(Buttons.LeftThumbstickDown, controllingPlayer, out playerIndex);
    }

    // Tells the left paddle to move up
    public bool LeftUp(PlayerIndex? controllingPlayer)
    {
        PlayerIndex playerIndex;

        return IsNewKeyPress(Keys.Up, controllingPlayer, out playerIndex)
               || IsNewButtonPress(Buttons.DPadUp, controllingPlayer, out playerIndex)
               || IsNewButtonPress(Buttons.LeftThumbstickUp, controllingPlayer, out playerIndex);
    }



// And now from my Gameplay class:

public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
........
input.Update();
            // Controls movement of the bats              
            if (rightBat.GetType() != typeof(AIBat))
            {
                if (input.LeftDown(ControllingPlayer))
                {
                    leftBat.MoveDown();
                }
                else if (input.LeftUp(ControllingPlayer))
                {
                    leftBat.MoveUp();
                }

                if (input.RightDown(ControllingPlayer))
                {
                    rightBat.MoveDown();
                }
                else if (input.RightUp(ControllingPlayer))
                {
                    rightBat.MoveUp();
                }


// From my bat class, so that you see what the MoveUp and MoveDown functions do:

    public Vector2 GetPosition()
    {
        return position;
    }

    public void MoveUp()
    {
        SetPosition(position + new Vector2(0, -moveSpeed));
    }

    public void MoveDown()
    {
        SetPosition(position + new Vector2(0, moveSpeed));
    }
\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

First I see a naming issue: You're using a method named LeftDown to check if the down arrow key is currently pressed. You might want to rename it to IsLeftPlayerGoingDown or something less ambiguous like that. At first glance, I thought "LeftDown" meant it checked whether the left arrow key was down.

Now, your LeftDown / IsLeftPlayerGoingDown method checks if there was a new key or button press (during the last frame). You should just check whether it's currently down, not if it has just been pressed. So your code would be something like:

public bool LeftDown(PlayerIndex? controllingPlayer)
{
    PlayerIndex playerIndex;

    return IsKeyPressed(Keys.Down, controllingPlayer, out playerIndex)
           || IsButtonPressed(Buttons.DPadDown, controllingPlayer, out playerIndex)
           || IsButtonPressed(Buttons.LeftThumbstickDown, controllingPlayer, out playerIndex);
}

And you'll have to define IsKeyPressed and IsButtonPressed to check against your Current{something}State (something being Keyboard or GamePad), ignoring the Last{something}State.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks! Worked like a charm! For those who were curious, I followed his instructions, and created another helper, one for KeyPressed and another for ButtonPressed. It was nearly identical to the helper I previously had, and now checks against the current state. \$\endgroup\$ Commented May 25, 2012 at 13:48

You must log in to answer this question.

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