「任意のボタンの押下」の検出


10

プレーヤーが任意のボタンを押してメインページから続行できるようにしようとしています。これを行うには、ボタンのリストを作成し、ボタンをループして、ボタンの1つがダウンしていないかどうかを確認しました。しかし、私はこのコードがちょっと醜いと感じ、私が考えていないより簡単な方法があるかどうか疑問に思いますか?

これが私のコードが今どのように見えるかです:

            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 2013

@ジョン大きなIFループとは何ですか。
craftworkgames

この質問で得られるすべての反応が気に入っています。@Katuは「正しい」答えを得たと思います。
セスバティン2013

回答:


10

これでうまくいくはずです。すべての更新ループの最後に、の状態を保存しますpreviousGamePadState。次に、emを比較できます。これは、変更をすばやく検出する方法です。ループする必要はありません。

GamePadState.PacketNumber

PacketNumberを使用して、入力状態が変化したかどうかを判別できます。GetStateへの2つの連続した呼び出し間で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プロパティ


OPが使用しているように見えるコンテキストに近い、for GamePadStateenum Buttonsにこれを記述する類似の方法があります。
セスバティン2013

1
朝のコーヒーの前に何も答えてはいけません:)
Katu 2013

1
今ではそれは仕事をし、これより速くなることはできません。
Katu 2013

おっと、まったく違う方法だし、それが最速だと思う。いいね。
セスバティン2013

ボタンの押下のみを検出しますか、それともボタンのリリースも検出しますか?
George Duckett 2013

1

リフレクションの使用を気にしない場合は、次のようなものを使用できます(おそらくこれもまったく同じです)。

        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.

}

これが機能するかどうかはわかりません。私はそれをやろうとしたことがありません。うまくいったかどうか教えてください。
セスバティン2013

賢いアイデアですが、GamePadStateがEqualsをオーバーライドする可能性が高い場合にのみ機能します。ほとんどの場合、これは参照の等価性を使用するため、上記のifステートメントは真に評価されません。
craftworkgames

@craftworkgames Equalsは異なります。2つの参照が同じインスタンスであるかどうかを比較します。しかしGamePadState、==演算子をオーバーロードしてそれらの値を比較していますが、これは私の回答でリンクしました(op_Equality)。
セスバティン2013

実際、GamePadStateがおそらく機能する構造体であることに気づきませんでした。技術的には、Equalsと==の動作は多くの場合同じですが、もちろん実装によって異なりますが、ガイドラインではこのように推奨しています。あなたは本当に参照の等価をしたい場合もありますobject.ReferenceEquals msdn.microsoft.com/en-us/library/bsc2ak47.aspx
craftworkgames

そうですね、GamePadStateは値型なので、関係ありません。とにかく、==はオーバーロードされているため、IMOを使用することもできます。
セスバティン2013

1

ボタンは列挙型なので、次のようにEnum.GetValuesメソッドを使用できます。

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

foreach (var button in buttonList)
{
    if (GamePad.GetState(PlayerIndex.One).IsButtonDown(button))
        ExitMainMenu= true;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.