Mendeteksi "Semua Tombol Tekan"


10

Saya mencoba untuk mengizinkan pemain untuk menekan tombol apa saja untuk melanjutkan dari halaman utama. Saya bisa melakukan ini dengan membuat Daftar Tombol dan mengulanginya dan memeriksa salah satunya turun; Namun, saya merasa kode ini jelek dan bertanya-tanya apakah ada cara yang lebih sederhana untuk melakukannya yang tidak saya pikirkan?

Inilah kode saya saat ini:

            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;
                }
            }

Saya pribadi hanya akan melakukan loop IF besar, sebagai lawan membuat array dan looping
jgallant

@ Jon Apa itu lingkaran IF besar dan mengapa akan lebih baik?
craftworkgames

Saya suka semua respons yang didapat pertanyaan ini. Saya pikir @ Katu mendapat jawaban yang "benar".
Seth Battin

Jawaban:


10

Ini harus melakukan pekerjaan. Di akhir setiap pembaruan, simpan status previousGamePadState. Maka Anda dapat membandingkan mereka. Ini adalah cara cepat untuk mendeteksi perubahan. Tidak perlu diulang.

GamePadState.PacketNumber :

Anda dapat menggunakan PacketNumber untuk menentukan apakah keadaan input telah berubah. Jika nilai PacketNumber tetap sama antara dua panggilan berurutan ke GetState, maka belum ada perubahan dalam input.

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;
}

EDIT: Diubah ke metode. Ini tidak dijamin berfungsi dengan benar, tetapi harus berfungsi. Juga, karena ini benar-benar mendeteksi perubahan input, jadi jika pengguna melepaskan tombol, hal ini juga terlihat. Saya juga menambahkan ifuntuk mendeteksi gerakan thumbstick, sehingga Anda bisa mengabaikannya setidaknya.

Semoga ini bisa membantu Anda. Beri tahu saya, jika tidak sesuai dengan kebutuhan Anda, saya yakin kami bisa menyelesaikannya.

Cara: Mendeteksi Apakah Tombol Pengendali Telah Ditekan Bingkai Ini GamePadState.PacketNumber Properti


Ada cara analog untuk menulis ini GamePadStatedan enum Buttons, yang lebih dekat ke konteks OP tampaknya menggunakan.
Seth Battin

1
Seharusnya tidak menjawab apa pun sebelum kopi pagi :)
Katu

1
Sekarang ini berfungsi dan tidak bisa lebih cepat dari ini.
Katu

Wah, metode yang sama sekali berbeda, dan saya pikir Anda benar tentang itu menjadi yang tercepat. Bagus.
Seth Battin

Apakah itu mendeteksi hanya tombol yang ditekan, atau apakah itu juga mendeteksi pelepasan tombol?
George Duckett

1

Jika Anda tidak keberatan menggunakan Refleksi, Anda dapat menggunakan sesuatu seperti ini (bahkan mungkin ini persis):

        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

Anda bisa secara manual membuat yang kosongGamePadState , dan kemudian memeriksanya (dalam) kesetaraan dengan yang asli saat ini, yang Anda ambil dengan menelepon 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.

}

Saya tidak tahu apakah ini berhasil; Saya belum pernah mencoba melakukannya. Beri tahu saya jika itu berhasil untuk Anda.
Seth Battin

Ide pintar, meskipun itu hanya akan berfungsi jika GamePadState menimpa Equals yang tidak mungkin. Kemungkinan besar, itu akan menggunakan referensi kesetaraan dan karenanya pernyataan di atas jika tidak akan pernah mengevaluasi untuk benar.
craftworkgames

@ craftworkgames Equalsberbeda; itu membandingkan dua referensi untuk menjadi contoh yang sama. Tetapi GamePadStateapakah overload operator == untuk membandingkan nilai-nilai mereka, yang saya tautkan dalam jawaban saya ( op_Equality).
Seth Battin

Sebenarnya saya tidak menyadari bahwa GamePadState adalah struct yang mungkin akan bekerja. Namun secara teknis, perilaku Equals dan == seringkali sama, tentu saja, itu tergantung pada implementasinya tetapi pedoman merekomendasikannya dengan cara ini. Jika Anda benar-benar ingin referensi kesetaraan, Anda juga ada objek.Referensi Setara dengan msdn.microsoft.com/en-us/library/bsc2ak47.aspx
craftworkgames

Ah Anda benar, GamePadState adalah tipe nilai, jadi tidak relevan. Apapun, == kelebihan beban, sebaiknya gunakan IMO.
Seth Battin

1

Karena Buttons adalah enumaration Anda dapat menggunakan metode Enum.GetValues seperti ini:

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

foreach (var button in buttonList)
{
    if (GamePad.GetState(PlayerIndex.One).IsButtonDown(button))
        ExitMainMenu= true;
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.