การลบความล่าช้าเมื่อเริ่มต้นการกดปุ่ม


11

ฉันกำลังสร้างเกมง่ายๆและหนึ่งในปัญหาที่ฉันพบคือความล่าช้าที่น่ารำคาญเมื่อกดปุ่มอย่างต่อเนื่อง

ดังนั้นโดยทั่วไปเมื่อฉันกด (เป็นเวลานานมาก) ตัวอย่างเช่นUpวัตถุของฉันจะเคลื่อนที่ 1 หน่วยขึ้นไปไม่ขยับ (ประมาณ 1 วินาที) จากนั้นเลื่อนอย่างต่อเนื่อง 1 หน่วยขึ้นไป (โดยไม่ล่าช้า)

ขณะนี้ฉันใช้สิ่งนี้เพื่อย้ายวัตถุ (SDL2):

while (SDL_PollEvent(&event))
{
    switch (event.type)
    {
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym)
        {
        case SDLK_UP:
            //Move object 1 unit up
            break;
        //Other unrelated things omitted
        }
        break;
    //Omitted other cases
    }
}

สิ่งที่ฉันต้องการคือการลบความล่าช้าเพื่อให้วัตถุสามารถเคลื่อนที่Upได้อย่างรวดเร็วในทันที มีวิธีการทำเช่นนี้?

คำตอบ:


19

ด้วยการรอให้เหตุการณ์สำคัญถูกดาวน์โหลดคุณมีโอกาสที่จะได้รับอัตราการทำซ้ำเหตุการณ์สำคัญที่ระบบปฏิบัติการควบคุม (และผู้ใช้สามารถระบุตัวเองได้)

แต่คุณอาจต้องการโทรไปSDL_GetKeyboardStateที่ด้านบนของลูปการอัปเดตเกมของคุณ (ส่วนหนึ่งของการอัปเดตที่เกิดขึ้นทุกเฟรมไม่ว่าจะมีเหตุการณ์เข้ามาหรือไม่) เพื่อรับสถานะของแป้นพิมพ์และตรวจสอบว่า คีย์ไม่ทำงานหรือไม่ระหว่างเฟรมแต่ละเฟรม


การฟังข้อความจากหน้าต่างจะดีกว่าไหม การใช้การสำรวจบางครั้งฉันพลาดการกดปุ่มสั้น ๆ และปัญหานี้แย่ลงเมื่ออัตราเฟรมต่ำ
รอยต

@RoyT มันขึ้นอยู่กับเกมของคุณและประเภทของการกระทำที่คุณต้องการกระตุ้นด้วยปุ่ม หากการกดปุ่มเป็นสิ่งที่อยู่ครั้งเดียวเช่นเดียวกับคีย์ "การกระทำ" ซึ่งปิดกล่องโต้ตอบคิวข้อความนั้นเป็นแนวทางที่ถูกต้อง - คุณต้องการฟังเหตุการณ์อะตอมมิก - ในทางกลับกันสถานะคีย์แสดงถึงสถานะต่อเนื่องเช่นคีย์ "ย้าย" ตรรกะมักจะwhile key UP is down move 30 units per second- และต่อวินาทีจะสมเหตุสมผลเมื่อคุณมีเวลาที่วัดได้ระหว่างคีย์ลงและขึ้น - มักจะมากกว่าหนึ่งเฟรม
Falco

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

และตามเฟรมคุณหมายถึงขีดเกมไม่ใช่เฟรมวิดีโอใช่ไหม เพราะเราไม่ได้เล่นเกมและเข้ารหัสตรรกะของเกมในลูปการเรนเดอร์ :-)
corsiKa

@JoshPetrie ฉันเห็นด้วยอย่างยิ่งเพียงแค่ต้องการชี้ให้เห็นข้อแม้เล็ก ๆ นี้ถ้าคุณต้องการตรวจสอบ 'คลิก' แทนที่จะเป็น 'กด' :)
Roy T.

10

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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.