การสอดแทรกตำแหน่งในเกมที่มีผู้เล่นหลายคน


14

เพื่อประหยัดแบนด์วิดธ์ในเกมที่มีผู้เล่นหลายคนของฉันฉันจะไม่อัปเดตทุกออบเจ็กต์ทุก ๆ เห็บเซิร์ฟเวอร์แทนแต่ละอ๊อพเจ็กมีอัปเดตให้คะแนนซึ่งบอกเกมว่าวัตถุนี้คาดว่าจะได้รับการอัพเดท

เมื่อฉันได้รับข้อความอัปเดตสำหรับวัตถุฉันคำนวณเวลาที่ฉันคาดว่าจะมีการอัพเดทครั้งต่อไป:

origin = serverCurrentPosition
diff = serverNextPosition - origin
arriveTime = now + timeBetweenTicks * updateRate

เมื่อฉันวาดวัตถุฉันจะคำนวณเวลาที่เหลือจนถึงการอัปเดตครั้งถัดไปและแก้ไขตำแหน่งตามนั้น:

step = 100 / timeBetweenTicks * updateRate
delta = 1 - step * ((arriveTime - now) / 100)
position = origin + diff * delta

มันใช้งานได้ ... แต่ยังมีความกระวนกระวายใจเล็กน้อยในการวาดแม้ว่าในทฤษฎีของฉันทุกสิ่งควรจะทำงานได้ดีเพราะมาตราส่วนควรดูแลความล่าช้าบางอย่างใช่ไหม?

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


สวัสดี Ivo ฉันคิดว่านี่เป็นหัวข้อที่ดี แต่ยังไม่ชัดเจนว่าโค้ดของคุณทำอะไรตัวอย่างเช่น serverCurrentPosition, serverNextPosition, เวลาที่มาจากช่องไหน
CiscoIPPhone

นั่นคือการส่งข้อมูลการอัพเดทที่มาจากเซิร์ฟเวอร์
Ivo Wetzel

คำตอบ:


11

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

ดังนั้นเมื่อคุณพึ่งได้รับการอัพเดทในเวลาที่กำหนดคุณจะมาถึงจุดหมายอย่างต่อเนื่องก่อน / หลังการอัพเดทจริง ดังนั้นกระวนกระวายใจ

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

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


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

ค่อนข้างเป็นไปได้ หากการเปิดใช้การเร่งความเร็วทำให้อัตราเฟรมสูงขึ้นความน่าจะเป็นในการจัดการข้อมูลการอัพเดทในเวลาที่เหมาะสมนั้นเพิ่มขึ้นอย่างแน่นอน
ไม่เป็นไร

9

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

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

ฉันรวมรายละเอียดมากมายเกี่ยวกับวิธีการนี้ไว้ในคำตอบก่อนหน้าของฉันที่นี่


หืมฉันทำอะไรแบบนั้นในเวอร์ชั่นก่อนหน้าจุดลอยตัวที่ไม่แน่ชัดทำให้มันแย่มากในบางครั้งฉันมีช่วงเวลาที่ใหญ่ระหว่างการอัปเดตถึง 300 มิลลิวินาทีสำหรับวัตถุบางอย่าง แต่บางทีฉันทำผิดฉันจะให้มันผิด ยิงเมื่อฉันหาเวลาว่าง :)
Ivo Wetzel

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

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