ตรวจจับ“ การกดปุ่มใด ๆ ”


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 วงใหญ่แทนการสร้าง array และ looping
jgallant

@ จอน IF วงใหญ่คืออะไรและทำไมมันถึงดีกว่า
craftworkgames

ฉันรักการตอบสนองทั้งหมดที่คำถามนี้ได้รับ ฉันคิดว่า @Katu ได้คำตอบว่า "ถูกต้อง"
เซทแบตทิน

คำตอบ:


10

สิ่งนี้ควรทำงาน previousGamePadStateในท้ายที่สุดของวงปรับปรุงทุกคนบันทึกสถานะของ จากนั้นคุณสามารถเปรียบเทียบ em นี่เป็นวิธีที่รวดเร็วในการตรวจจับการเปลี่ยนแปลง ไม่จำเป็นต้องวนซ้ำ

GamePad สถานะแพคเก็ตจำนวน :

คุณสามารถใช้ PacketNumber เพื่อตรวจสอบว่าสถานะอินพุตมีการเปลี่ยนแปลงหรือไม่ หากค่าของ PacketNumber ยังคงเหมือนเดิมระหว่างการโทรตามลำดับสองครั้งไปยัง GetState แสดงว่าไม่มีการเปลี่ยนแปลงอินพุต

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.Packet หมายเลขคุณสมบัติ


มีวิธีคล้ายกันในการเขียนสิ่งนี้สำหรับGamePadStateและenum Buttonsซึ่งใกล้เคียงกับบริบทที่ OP ดูเหมือนว่าจะใช้
เซทแบตทิน

1
ไม่ควรตอบอะไรก่อนกาแฟตอนเช้า :)
Katu

1
ตอนนี้ทำงานและไม่สามารถรับได้เร็วกว่านี้
Katu

โอ้โหวิธีที่แตกต่างอย่างสิ้นเชิงและฉันคิดว่าคุณพูดถูกมันเป็นวิธีที่เร็วที่สุด ดี
เซทแบตทิน

ตรวจพบว่ากดปุ่มเพียงปุ่มเดียวหรือตรวจพบการกดปุ่มหรือไม่
George Duckett

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 แทนที่เท่านั้นซึ่งไม่น่าเป็นไปได้ ส่วนใหญ่แล้วมันจะใช้ความเท่าเทียมกันในการอ้างอิงดังนั้นข้อความข้างต้นถ้าไม่เคยประเมินว่าเป็นจริง
craftworkgames

@craftworkgames Equalsนั้นแตกต่างกัน มันเปรียบเทียบการอ้างอิงสองรายการสำหรับการเป็นอินสแตนซ์เดียวกัน แต่GamePadStateจะโอเวอร์โหลดตัวดำเนินการ == เพื่อเปรียบเทียบค่าของพวกเขาซึ่งฉันเชื่อมโยงกับคำตอบของฉัน ( op_Equality)
เซทแบททิน

จริงๆแล้วฉันไม่ทราบว่า GamePadState เป็นโครงสร้างที่อาจใช้งานได้ แม้ว่าในทางเทคนิคแล้วพฤติกรรมของ Equals และ == มักจะเหมือนกันแน่นอนว่ามันขึ้นอยู่กับการใช้งาน แต่แนวทางก็แนะนำด้วยวิธีนี้ หากคุณต้องการความเท่าเทียมกันของการอ้างอิงอย่างแท้จริงคุณยังมีวัตถุการอ้างอิงข้อเขียน msdn.microsoft.com/en-us/library/bsc2ak47.aspx
craftworkgames

คุณคิดถูกแล้ว GamePadState เป็นประเภทค่าดังนั้นจึงไม่เกี่ยวข้อง โดยไม่คำนึงถึง == มีการใช้งานมากเกินไปอาจใช้ IMO ได้เช่นกัน
เซทแบตทิน

1

เนื่องจาก Buttons เป็น enumaration คุณสามารถใช้วิธี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.