检测“按下任何按钮”


10

我正在尝试允许播放器按任意按钮以从主页继续。我可以通过创建按钮列表并循环浏览这些按钮并检查其中一个按钮是否关闭来做到这一点。但是,我觉得这段代码很难看,想知道是否有一种我没有想到的简单方法?

这是我的代码现在的样子:

            if (GamePad.GetState(PlayerIndex.One).IsConnected)
            {
                var buttonList = new List<Buttons>()
                {
                    {Buttons.A},
                    {Buttons.B},
                    {Buttons.Y},
                    {Buttons.X},
                    {Buttons.Start},
                    {Buttons.Back},
                    {Buttons.RightShoulder},
                    {Buttons.LeftShoulder},
                    {Buttons.RightTrigger},
                    {Buttons.LeftTrigger}
                };

                foreach (var button in buttonList)
                {
                    if (GamePad.GetState(PlayerIndex.One).IsButtonDown(button))
                        ExitMainMenu= true;
                }
            }

我个人只是做一个大的IF循环,而不是创建数组和循环。
jgallant

@Jon什么是大的IF循环,为什么会更好?
craftworkgames

我喜欢这个问题得到的所有答复。我认为@Katu虽然得到了“正确”的答案。
塞斯·巴丁

Answers:


10

这应该做的工作。在每个更新循环的最后,保存的状态previousGamePadState。然后,您可以比较em。这是检测更改的快速方法。无需循环。

GamePadState.PacketNumber

您可以使用PacketNumber确定输入状态是否已更改。如果在两次连续调用GetState之间,PacketNumber的值保持相同,则输入没有变化。

public bool HasInputChanged(GamePadState previousGamePadState, bool ignoreThumbsticks)
{ 
    GamePadState currentState = GamePad.GetState( PlayerIndex.One );
    if ((currentState.IsConnected) && (currentState.PacketNumber != previousGamePadState.PacketNumber))
    {
        //ignore thumbstick movement
        if ((ignoreThumbsticks == true) && ((currentState.ThumbSticks.Left.Length() != previousGamePadState.ThumbSticks.Left.Length() )&&(currentState.ThumbSticks.Right.Length() != previousGamePadState.ThumbSticks.Right.Length()) ))
            return false;
        return true
    }
    return false;
}

编辑: 更改为方法。它不能保证按原样工作,但应该可以工作。同样,因为这确实检测到输入的变化,所以如果用户释放按钮,也可以看到它。我还添加if了检测指尖移动的功能,因此您至少可以忽略它们。

希望这对您有帮助。让我知道,如果它不适合您的需求,我相信我们可以解决。

如何:检测是否已按下此框架 GamePadState.PacketNumber属性的控制器按钮


有一种类似的方式可以为GamePadState和编写代码enum Buttons,这更接近于OP似乎正在使用的上下文。
塞斯·巴丁

1
早上喝咖啡之前不应该回答任何问题:)
卡图

1
现在,它可以完成工作,而且没有比这更快的速度了。
卡图

哇,完全不同的方法,我认为您是对的,因为它是最快的。真好
塞斯·巴丁

这是否仅检测按钮的按下,还是也检测按钮的释放?
2013年

1

如果您不介意使用Reflection,则可以使用类似这样的东西(可能甚至是这样):

        var properties = typeof(GamePadButtons).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (var property in properties)
        {
            var value = property.GetValue(GamePad.GetState(PlayerIndex.One).Buttons);
            if (value is ButtonState && (ButtonState)value == ButtonState.Pressed)
                ExitMainMenu = true;
        }

1

您可以手动构造一个空容器GamePadState,然后通过调用来获取与当前真实容器的不相等性GamePad.GetState

playerInput = GamePad.GetState(PlayerIndex.One);  
emptyInput = new GamePadState(Vector2.Zero, Vector2.Zero, 0, 0);
if (playerInput != emptyInput){

    // yay!!!!, a button push!
    // 
    // P.S., remember to allow any PlayerIndex to take control of the the game 
    // from the main menu.  It sucks when you pick up controller2 and it doesn't work.

}

我不知道这行不通。我从未尝试过这样做。让我知道是否适合您。
塞斯·巴丁

聪明的主意,尽管只有在GamePadState覆盖Equals时才可行,但这不太可能。最有可能的是,它将使用引用相等性,因此上述if语句永远不会评估为true。
craftworkgames

@craftworkgames Equals是不同的;它比较两个引用是否相同。但是GamePadState会重载==运算符以比较它们的值,我在答案(op_Equality)中链接了它们。
塞斯·巴丁

实际上我没有意识到GamePadState是一个可能会起作用的结构。从技术上讲,Equals和==的行为通常是相同的,当然,这取决于实现方式,但是准则建议采用这种方式。如果您确实希望引用相等,那么您也有反对。ReferenceEqualsmsdn.microsoft.com/ en
craftworkgames

没错,GamePadState是一种值类型,因此不相关。无论如何,==已过载,不妨使用IMO。
塞斯·巴丁

1

由于Buttons是一种枚举,因此您可以使用Enum.GetValues方法,如下所示:

var buttonList = (Buttons[])Enum.GetValues(typeof(Buttons));

foreach (var button in buttonList)
{
    if (GamePad.GetState(PlayerIndex.One).IsButtonDown(button))
        ExitMainMenu= true;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.