คีย์ผสมบนอินพุตจากโพล


9

ดังนั้นสมมติว่าคุณมีระบบอินพุตที่อิงกับการสำรวจ

void update()
{
    if( Keyboard[ 'A' ] )
        // A is down
}

สมมติว่าคุณต้องการจดจำการผสมคีย์ความยาว 3 ถึง 8 ชุด (เช่นลง, ไปข้างหน้า, ไปข้างหน้า, A สำหรับ Hado-ken)

ที่คุณจะวิธีที่ดีที่สุดสร้างทั่วไป (สามารถปรับเปลี่ยนได้อย่างง่ายดายโปรแกรมได้ /) ระบบการป้อนข้อมูลที่สำคัญในการรวมกันถึงขนาดป้อนข้อมูล?

คำตอบ:


7

พื้นฐานคุณไม่สามารถ คีย์ผสมจำเป็นต้องมีการสั่งซื้อและการสั่งซื้อจำเป็นต้องมีเหตุการณ์

สิ่งที่คุณสามารถทำได้คือเปลี่ยนการโพลให้เป็นเหตุการณ์โดยการเปรียบเทียบสถานะหลักแต่ละเฟรมและสร้างเหตุการณ์หลังเหตุการณ์ที่เกิดขึ้นจากความแตกต่าง ไม่น่าเชื่อถือเนื่องจากคุณสูญเสียการประทับเวลาและการสั่งซื้อภายในเฟรมอื่น ๆ ที่ระบบเหตุการณ์ "ดั้งเดิม" ให้ แต่จะช่วยให้คุณสามารถตรวจจับและสั่งซื้ออย่างน้อยหนึ่งคีย์ต่อหนึ่งเฟรม

เมื่อคุณมีเหตุการณ์ที่สั่งซื้อแล้วคุณสามารถใช้เครื่องสถานะ จำกัด หรือเครื่องมืออื่น ๆ เพื่อจับคู่กับรายการย้ายของคุณและดำเนินการอย่างถูกต้อง


เป็นการทำให้เข้าใจผิดเล็กน้อยที่จะบอกว่าคุณไม่สามารถทำสิ่งนี้ได้หากไม่มีเหตุการณ์ ในทางเทคนิคเหตุการณ์เป็นเพียงวิธีเรียกเมธอดหรือรายการเมธอดเมื่อตรงตามเงื่อนไขบางประการ ในแง่นั้นคุณต้องการกิจกรรม อย่างไรก็ตามฉันสามารถใช้เหตุการณ์คำ (ไม่เหมาะสม) กับงานเขียนโปรแกรมจำนวนมากที่เหมาะสมกับคำอธิบายนั้น ฉันได้เพิ่มคำตอบที่แก้ปัญหาในแบบที่ฉันมักจะทำซึ่งไม่ได้ใช้สิ่งที่โปรแกรมเมอร์ส่วนใหญ่มักจะคิดว่าเป็น "เหตุการณ์"
Olhovsky

2
รหัสของคุณทำสิ่งที่ฉันบอกว่าจะทำโดยไม่มีเหตุการณ์ แต่ไม่สนใจคำเตือน - ซึ่งเป็นสิ่งที่คุณสูญเสียการสั่งซื้อภายในเฟรม เมื่อคุณได้รับเหตุการณ์จากวงวนข้อความ Win32 คุณจะได้รับลำดับที่มีความละเอียดมากกว่า glob ต่อเฟรม เมื่อคุณคำนวณ deltas ด้วยตัวเองคุณจะสูญเสียสิ่งนั้นไป สำหรับเกมต่อสู้ที่ผู้เล่นสามารถป้อนคอมโบได้หลายส่วนในเฟรมเดียวคุณต้องรู้ว่าเกมเหล่านั้นอยู่ในสภาพหรือไม่เรียบร้อย

ยุติธรรมพอสมควร โดยมีเงื่อนไขว่าเรากำลังโพลที่ 60hz ฉันสงสัยว่าเราต้องการแยกความแตกต่างระหว่างการกดที่น้อยกว่า 16ms นอกเหนือจากที่ 60Hz ให้การเลือกตั้ง (สมมติว่าผู้เล่นของเราเป็นมนุษย์)
Olhovsky

พวกเราทำ. ผู้เล่นเกมต่อสู้ที่มีฝีมือสามารถป้อนคำสั่ง hadouken / shoryuken stick ในเวลาน้อยกว่าสามเฟรมซึ่งหมายความว่าเราต้องแยกความแตกต่างระหว่างพวกเขา

จากนั้นคุณต้องสำรวจความคิดเห็นบ่อยกว่า 60hz
Olhovsky

3

วิธีหนึ่งคือการจัดเก็บสถานะอินพุตปัจจุบันและก่อนหน้าและเปรียบเทียบทุกครั้งที่คุณสำรวจความคิดเห็นอินพุต

สำหรับแต่ละคีย์ที่สามารถกดได้ให้จัดเก็บวัตถุที่มีการประทับเวลาครั้งล่าสุดที่คีย์เปลี่ยนจากสถานะลงเป็นสถานะขึ้น

อัปเดตวัตถุเหล่านี้โดยทำสิ่งนี้ในทุกโพล:

void update(){
    some_key_has_been_pressed = false;
    foreach(key in keys){
        if(previous_input[key].Down && current_input[key].Up){
            keys[key].up_timestamp = current_time();
        }

        if(current_input[key].Down){
            keys[key].down_timestamp = current_time();
            some_key_has_been_pressed = true;
        }
    }
}

ตอนนี้คุณสามารถจับคู่รูปแบบคอมโบกับเนื้อหาของ keysตอนนี้คุณสามารถตรงกับรูปแบบคอมโบของคุณกับเนื้อหาของ

มีคำสั่งผสมวัตถุสำหรับแต่ละคำสั่งผสมและเรียกการปรับปรุง () ในแต่ละคำสั่งผสมวัตถุที่แต่ละโพล

เมธอด update () ของวัตถุคอมโบจะจัดรูปแบบให้ตรงกับคอมโบโดยตรวจสอบว่าเงื่อนไขที่จำเป็นทั้งหมดสำหรับคอมโบนั้นเป็นไปตามแบบสำรวจนี้หรือไม่ นั่นคือการประทับเวลาของปุ่มทั้งหมดสำหรับคำสั่งผสมจนถึงตอนนี้อยู่ในลำดับและไม่มีปุ่มอื่นใดที่จะทำลายคำสั่งผสมได้ถูกกดเฟรมนี้ สำหรับแต่ละเงื่อนไขตรงเพิ่มเคาน์เตอร์ในวัตถุคำสั่งผสมกับเงื่อนไขถัดไปเพื่อตรวจสอบ เมื่อตรงตามเงื่อนไขทั้งหมดในคอมโบให้เรียกวิธีที่คอมโบนั้นควรปฏิบัติ หากsome_key_has_been_pressed == trueแต่ไม่ได้กดคีย์ที่เป็นเงื่อนไขถัดไปสำหรับคอมโบให้รีเซ็ตตัวนับเงื่อนไขที่พอใจของคอมโบเป็น 0

ข้างต้นเป็นวิธีการที่ฉันชอบเพราะง่ายต่อการใช้งานบำรุงรักษาง่ายมีประสิทธิภาพและแยกส่วนได้สูง

อย่างไรก็ตามสำหรับวิธีที่ดีอีกวิธีหนึ่งลองดูตัวอย่างลำดับการป้อนข้อมูล XNAซึ่งเขียนเป็น C # และตรรกะนั้นมีแนวโน้มที่จะถ่ายโอนไปยังภาษาที่คุณกำลังใช้


ในคำสั่ง if ที่สองif(current_input[key].down){คุณไม่ต้องการตรวจสอบว่าคีย์นั้นอยู่ในprevious_inputสถานะหรือไม่ down_timestampตามที่เขียนไว้ผมคิดว่ามันอย่างต่อเนื่องจะปรับปรุงที่สำคัญที่จัดขึ้นของ
webdevkit

การอัพเดตการประทับเวลาลงอย่างต่อเนื่องเป็นพฤติกรรมที่ตั้งใจไว้ สิ่งนี้ช่วยให้คุณสามารถเปรียบเทียบ up_timestamp และ down_timestamp ของคีย์ใด ๆ เพื่อตรวจสอบว่ามันถูกเก็บไว้นานเท่าใด หากคุณกดปุ่มค้างไว้อย่างต่อเนื่องคุณจะไม่เปลี่ยน up_timestamp ดังนั้น (down_timestamp - up_timestamp) จะยังคงให้ระยะเวลาที่ใช้งาน
Olhovsky

ขอขอบคุณสำหรับการชี้แจง. ฉันคิดตรงกันข้ามซึ่ง up_timestamp - down_timestamp คือระยะเวลาของคีย์ที่พักไว้
webdevkit

1

สร้างสแต็กของเหตุการณ์คีย์ X สุดท้ายสำหรับแต่ละเหตุการณ์สำคัญเพิ่มวัตถุด้วยคีย์และเวลาของการกด / ปล่อยจากนั้นตรวจสอบว่าสมาชิกคนสุดท้ายของสแต็กตรงกับรูปแบบพิเศษและหากกดปุ่มเหล่านั้นเร็วพอที่จะ นับเป็นการรวมกัน ในที่สุดก็นำวัตถุที่เก่าแก่ที่สุดออกจากสแต็ก


2
สแต็คที่คุณสามารถลบวัตถุด้านล่างจากไม่ได้จริงๆกอง;)
Olhovsky

กลุ่มของข้อมูลที่เรียงลำดับรายการอาจเป็นคำที่ถูกต้อง
aaaaaaaaaaaa

deque;) O (1) enq / deq ftw
michael.bartnett

3
ลำดับที่ได้รับคำสั่งที่วัตถุถูกวางลงบนปลายด้านหนึ่งและลบออกจากที่อื่น ๆ จะเรียกว่ามากที่สุดอย่างถูกต้องคิว

1
คุณสามารถสร้าง ring-buffer (BufferLength> = คำสั่งที่ยาวที่สุด) และเขียนคีย์ลงไป (Position = Number MOD BufferLength) ไม่มีการเพิ่ม / ลบจะต้องทั้งหมด
Kromster
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.