การใช้เวลาว่างในเกมเทิร์นเบส (RPG) สำหรับการอัพเดต


9

หากคุณใช้เกมอาร์พีจีเทิร์นใดก็ตามจะมีช่วงเวลาที่ยาวนานเมื่อไม่มีอะไรเกิดขึ้นเพราะเกมดังกล่าววนลูปมากกว่า 'wait_for_player_input' ดูเหมือนเป็นเรื่องสมเหตุสมผลที่จะใช้เวลานี้เพื่ออัปเดตสิ่งต่าง ๆ

อย่างไรก็ตามสิ่งนี้ดูเหมือนจะแนะนำทันทีว่าจะต้องมีเธรด การออกแบบแบบนี้มีความเป็นไปได้ไหมในเธรดเดี่ยว?

loop:  
if not check_something_pressed:  
    update_a_very_small_amount  
else  
  keep going

แต่ถ้าเราบอกว่า 'a_very_small_amount' เป็นเพียงการอัปเดตวัตถุชิ้นเดียวในแต่ละลูปมันจะช้ามากในการอัปเดต

คุณจะไปเกี่ยวกับเรื่องนี้โดยเฉพาะอย่างยิ่งในหัวข้อเดียวหรือไม่

แก้ไข: ฉันติดแท็กผู้ไม่เชื่อเรื่องภาษานี้เนื่องจากดูเหมือนว่าเป็นสิ่งที่สมเหตุสมผลแม้ว่าสิ่งใดที่เฉพาะเจาะจงกับงูหลามก็จะยิ่งใหญ่ ;-)

การแก้ไขครั้งที่สอง: เกมนี้ไม่ได้วางแผนที่จะมีองค์ประกอบแบบเคลื่อนไหว นั่นคือตอนนี้ฉันกำลังใช้งานมันเพื่อรอให้ผู้เล่นป้อนข้อมูลแล้วอัปเดตทุกอย่างแล้ววาด ดังนั้นแทนที่จะเป็น X FPS มันขึ้นอยู่กับความเร็วของผู้ใช้

คำตอบ:


7

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

สมมติว่าคุณกำหนดเป้าหมาย 60 FPS สำหรับเกมของคุณ นั่นทำให้คุณมีเวลา 16.667 ms ในการทำงานทั้งหมดที่คุณต้องทำในแต่ละเฟรม ที่จุดเริ่มต้นของเกมรับเวลาปัจจุบันโดยใช้ตัวจับเวลาความละเอียดสูงสุดที่มีอยู่เพิ่ม 16.667 ms ลงในนั้นและเก็บไว้ที่ใดที่หนึ่ง ฉันคิดว่าฟังก์ชั่นในไพ ธ อนเป็นเวลา () ถึงแม้ว่ามันจะใช้เวลานานแล้วตั้งแต่ฉันทำงานในภาษา หลังจากการประมวลผลของคุณเสร็จสมบูรณ์ให้ป้อนลูปที่ตรวจสอบเวลาปัจจุบันกับเวลาที่คุณบันทึกไว้ หากเวลาปัจจุบันน้อยกว่าเวลาสิ้นสุดเฟรมให้ update_a_very_small_amount ฉันไม่ต้องกังวลมากนักเกี่ยวกับการประมวลผลที่จะผ่านจุดสิ้นสุดของเฟรมเนื่องจากการอัปเดตขนาดเล็กของคุณน่าจะรวดเร็ว มันจะล่าช้าเพียงเล็กน้อยในการเริ่มต้นของเฟรมถัดไปและคุณมีเวลาว่างพอที่จะจัดการกับมัน

หลังจากการประมวลผลเฟรมเสร็จสิ้นให้เพิ่ม 16.667 ms ลงในเวลาที่จัดเก็บไว้ที่ส่วนท้ายของเฟรมสุดท้ายเพื่อดูว่าควรจะสิ้นสุดจุดใดของเฟรมถัดไป หากคุณใช้เวลาปัจจุบัน +16.667 ms และการประมวลผลจบลงการสิ้นสุดเฟรมถัดไปจะถูกผลักออกไปอย่างไรก็ตามเวลาที่เฟรมสุดท้ายวิ่งผ่าน

เรื่องการแก้ไขที่สอง

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


2

สำหรับPythonโดยเฉพาะคุณสามารถลองใช้Coroutinesเพื่อทำการคำนวณผ่านการเรียกใช้การอัพเดตหลายครั้ง

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

รายละเอียดการใช้งาน PEP-0342 coroutine ใน Python

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


1

ใช่มันเป็นไปได้ เกมของคุณจะมีเกมหลักบางประเภท บางสิ่งเช่นนี้

while(gameRunning)
{
  checkUserInput()
  updateGame()
  renderGame()
}

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

วิธีแยกมันขึ้นอยู่กับประเภทของเกมที่คุณกำลังสร้าง สมมติว่าคุณมีรูทีนตัวค้นหาพา ธ ซึ่งใช้ A * เพื่อคำนวณพา ธ ผ่านเขาวงกต คุณจะต้องหยุดอัลกอริทึมหลังจากระยะเวลาหนึ่งหรือหลังจากการวนซ้ำคงที่รักษาเส้นทางที่คำนวณไว้แล้วและกลับไปควบคุมกลับไปที่ลูปเกม การค้นหาเส้นทางจะดำเนินการต่อในครั้งถัดไปที่เรียกว่า updateGame คุณสามารถย้ายตัวละครไปตามเส้นทางบางส่วนในขณะที่มันยังคงคำนวณอยู่

เวลาส่วนใหญ่คุณไม่จำเป็นต้องกังวลเกี่ยวกับการโทรอัปเดตเกมที่ใช้เวลานานเกินไป

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


1

วิธีที่ฉันเข้าใจคำถามของคุณก็คือโดยทั่วไปคุณจะถามเกี่ยวกับการทำงานหลายอย่างพร้อมกัน

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

คำถามที่ดีกว่าในความคิดของฉันคือสิ่งที่ต้องทำในขณะที่รอให้ผู้เล่นย้าย สิ่งที่จะเป็นตัวประมวลผลที่เข้มข้นมากจนไม่สามารถทำการบินได้ในขณะเดียวกันในขณะเดียวกันก็เป็นทางเลือกที่ถ้าผู้เล่นทุบค้อนบางคนเลื่อนกุญแจเร็วพอเกมจะไม่มี ใช้เวลาในการประมวลผลเหล่านี้ ดังนั้นสิ่งต่าง ๆ เช่นการคำนวณ A * สำหรับ AIS สองพันรายการจะออกมา

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

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