วิธีรับและใช้เวลาเดลต้า


14

ฉันมีหนูมองและเดินในเกมของฉัน แต่พวกมันช้ามากและใช้งานยาก ฉันคิดว่าเป็นเพราะฉันใช้ความเร็วคงที่ ฉันได้ยินมาว่าในโครงการขนาดใหญ่ผู้พัฒนาใช้เวลาเดลต้า ฉันจะคำนวณเวลาเดลต้าในจำนวนที่มากเกินไปได้อย่างไร ฉันจะคำนวณความเร็วโดยใช้เวลาเดลต้าได้อย่างไร


C11 และ C ++ 11 ยังมีนาฬิการะดับนาโนวินาทีในตอนนี้: stackoverflow.com/a/36095407/895245 || stackoverflow.com/a/5524138/895245
Ciro Santilli 事件改造中心中心六四事件事件

คำตอบ:


18

"เวลาเดลต้า" เคยเป็นเวลาที่ผ่านไประหว่างการอัพเดตเฟรมสองครั้ง (แต่สามารถใช้ในบริบทอื่น ๆ ได้ซึ่งโดยปกติจะเป็นผลมาจากการลบเวลา)

คุณสามารถรับเวลาเดลต้าใน glut โดยใช้วิธีglutGetและพารามิเตอร์ GLUT_ELAPSED_TIME รวมทั้งการดำเนินการบางอย่าง

บรรทัดต่อไปนี้คืนค่าจำนวนมิลลิวินาทีนับตั้งแต่ glutInit ถูกเรียก (หรือการโทรครั้งแรกไปที่ glutGet (GLUT_ELAPSED_TIME)):

int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);

ดังนั้นหากคุณลงทะเบียน timeSinceStart ปัจจุบันที่แต่ละวนการเรนเดอร์คุณสามารถรู้ deltaTime โดยการลบอันเก่าไปยังอันใหม่

int oldTimeSinceStart = 0;

while( ... )
{
     int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);
     int deltaTime = timeSinceStart - oldTimeSinceStart;
     oldTimeSinceStart = timeSinceStart;

     //... stuff to update using deltaTime
}

นอกจากนี้คุณยังสามารถทำได้เกือบจะในลักษณะเดียวกันโดยใช้ไลบรารี C / C ++ ctimeพร้อมนาฬิกา ()และนิพจน์ค่าคงที่มาโครCLOCKS_PER_SECที่ระบุความสัมพันธ์ระหว่างติ๊กนาฬิกาและวินาที


โดยทั่วไปคุณสามารถใช้ deltaTime เพื่ออัปเดตการเคลื่อนไหวของคุณตามอัตราส่วนเป็นเวลาที่ผ่านไปนี้แทนที่จะใช้ค่าเวลาคงที่ ด้วยวิธีนี้ความเร็วในการเคลื่อนที่ของตัวละครของคุณควรจะใกล้เคียงกันหากโปรแกรมของคุณทำงานที่ 60 fps หรือหากทำงานที่ 10 fps


นี่คือตัวอย่างเล็ก ๆ : สมมติว่าคุณต้องการย้ายบางสิ่งบางอย่าง 10 หน่วยต่อวินาทีบนแกน x คุณสามารถทำสิ่งนี้ได้ (ถ้าเดลต้าไทม์ใช้มิลลิวินาทีอย่างแน่นอน)

Position.x += 10/1000 * deltaTime;

ด้วยวิธีนี้ไม่ว่าโปรแกรมของคุณจะอัปเดต 2 ครั้งหรือ 100 ครั้ง 1 วินาทีหลังจากนั้นตำแหน่งควรจะเกือบเหมือนเดิมและการเล่นเกมจะได้รับผลกระทบน้อยกว่าจากคอมพิวเตอร์ขนาดเล็กที่มีเฟรมต่อวินาทีต่ำกว่าหากใช้ค่าคงที่

  • ด้วยค่าคงที่ ==> low fps = การอัพเดทน้อย = การเคลื่อนไหวช้าในขณะที่ fps สูง = การปรับปรุงเพิ่มเติม = การเคลื่อนไหวที่เร็วมาก

  • ด้วย deltaTime ==> "เกือบ" การเคลื่อนไหวเดียวกัน


สุดท้ายคุณควรอ่านขั้นตอนเวลาคงที่เทียบกับขั้นตอนเวลาแปรผันบน gamedev.stackexchange


จะส่งคืนมิลลิวินาทีเป็นจำนวนเต็มหรือไม่ ขั้นต้นและอาจไม่เพียงพอ ฉันมักจะต้องใช้ตัวจับเวลาเฉพาะแพลตฟอร์มแล้วหลีกเลี่ยง GLUT เหมือนโรคระบาดเพราะมันไม่ดีสำหรับเกม
Sean Middleditch

@Sean ฉันไม่ได้ใช้ GLUT เหมือนกัน แต่นั่นเป็นพารามิเตอร์ของคำถามดังนั้นฉันจึงตอบคำถามนี้ในใจ;) อย่างไรก็ตามฉันสนใจตำแหน่งของคุณเกี่ยวกับ "ความไม่เพียงพอ" ของ int เพื่อจัดการมิลลิวินาทีในเกม . positive intมักจะไปถึง 2.147.483.647 ถ้าลงนามและถึง 4.294.967.295 ถ้าไม่ได้ลงนาม ... ดังนั้นแม้ถ้าเราพิจารณาที่มีขนาดเล็กหนึ่ง 2.147.483.647 มิลลิวินาทีเป็นเกือบ 25 วัน ... มันควรจะมากพอที่จะจัดการกับเกมมากที่สุด ตัวจับเวลาและแม้ว่าจะไม่เพียงพอเรายังคงสามารถใช้งานได้อย่างสมเหตุสมผลunsigned int(~ 50 วัน) หรือแม้แต่ a long long(อย่างที่ฉันมักจะทำ)
Valkea

1
@Valkea จุดไม่สูงสุดมันเป็นความละเอียดต่ำสุด เนื่องจากเฟรมเดียวที่ 60 FPS มีค่าเพียง 16 2 / 3rds ms ความแม่นยำ 1 มิลลิเซคอน (จากการแสดงมิลลิวินาทีเป็นจำนวนเต็ม) แสดงถึงขอบข้อผิดพลาดมากกว่า 5% - มากเกินพอที่จะส่งการจำลองไกลออกไป จำนวนไมโครวินาทีจะสามารถรับได้ แต่มิลลิวินาทีนั้นหยาบเกินไป
Steven Stadnicki

ใช่คุณต้องใช้เวลาหลายมิลลิวินาทีสำหรับสิ่งต่าง ๆ และตัวจับเวลาความละเอียดสูงเพื่อค้นหาสิ่งที่ GLUT ไม่ได้ให้ (ที่ฉันรู้) การเขียนโค้ดแพลตฟอร์มเพียงเล็กน้อยเพื่อใช้QueryPerformanceCounterบน Windows และgettimeofdayในส่วนอื่น ๆ นั้นไม่ได้เลวร้าย คุณจะต้องทำให้มือของคุณสกปรกและตั้งเป้าหมายให้น้อยกว่าตัวส่วนร่วมที่น้อยที่สุดของ API แพลตฟอร์มโดยเฉพาะใน C และ C ++
Sean Middleditch

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