एक मल्टीप्लेयर गेम में इंटरपोलिंग पोजीशन


14

अपने मल्टीप्लेयर गेम में बैंडविड्थ को बचाने के लिए , मैं हर सर्वर टिक को हर ऑब्जेक्ट को अपडेट नहीं करता, इसके बजाय प्रत्येक ऑब्जेक्ट में एक अपडेटरेट होता है जो गेम को बताता है कि यह ऑब्जेक्ट हर एक्स सर्वर टिक के अपडेट होने की उम्मीद है।

जब मैं किसी वस्तु के लिए एक अद्यतन संदेश प्राप्त करता हूं, तो मैं उस समय की गणना करता हूं जो मुझे अगले अद्यतन में आने की उम्मीद है:

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

जब मैं उस वस्तु को खींचता हूं जो अगले अद्यतन तक छोड़े गए समय की गणना करता है और तदनुसार स्थिति को प्रक्षेपित करता है:

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

यह काम करता है ... लेकिन ड्राइंग में अभी भी थोड़ा सा घबराहट है, हालांकि मेरे सिद्धांत में हर चीज को ठीक से काम करना चाहिए, क्योंकि स्केलिंग में कुछ मात्रा में अंतराल का ध्यान रखना चाहिए, इसे करना चाहिए?

तो यहाँ सवाल यह है कि क्या यह सबसे अच्छा तरीका है? क्या मुझे गणना में वास्तविक अंतराल डालना चाहिए? यदि हां, तो मैं यह कैसे करूंगा? मैंने कुछ experiements किया, लेकिन घबराना केवल बदतर हो गया।


हाय इवो। मुझे लगता है कि यह एक अच्छा विषय है, लेकिन यह स्पष्ट नहीं है कि आपका कोड क्या कर रहा है - उदाहरण के लिए जहां serverCurrentPosition, serverNextPosition, timeBetweenTicks आता है?
सिस्कोपफोन 3

यह सर्वर से आने वाले अपडेट डेटा में भेजा जाता है।
Ivo वेटज़ेल

जवाबों:


11

आपको घबराना है, क्योंकि आप अंतराल लगातार बदल रहे हैं। इसका मतलब यह है कि, जबकि सर्वर हर timeBetweenTicksटिक को अपडेट भेजता है , क्लाइंट कुछ चर समय के बाद उन्हें प्राप्त करता है। वह समय संभवतः timeBetweenTicksएक अच्छे कनेक्शन पर करीब है , लेकिन बिल्कुल बराबर नहीं है (और इसके अलावा, आपके पास सर्वर अंतराल और सर्वर और क्लाइंट पर अलग-अलग घड़ी की गति हो सकती है)।

इसलिए, जब आप निर्धारित समय में अपडेट प्राप्त करने पर भरोसा करते हैं, तो आप वास्तविक अपडेट से पहले / बाद में लगातार गंतव्य पर पहुंचते हैं। इसलिए, घबराना।

घबराहट को कम करने के लिए सरल दृष्टिकोण "रबर-बैंडिंग" का उपयोग कर रहा है, जो कि मार्टिन एक और उत्तर में सुझाते हैं। मूल रूप से, जब आप अपडेट प्राप्त करते हैं, तो आप तुरंत ऑब्जेक्ट की स्थिति को नहीं बदलते हैं। इसके बजाय, यदि क्लाइंट की स्थिति और सर्वर की स्थिति केवल थोड़ी भिन्न होती है, तो आप क्लाइंट की स्थिति को प्रक्षेपित करना शुरू करते हैं, ताकि कुछ निर्दिष्ट समय के बाद (जैसे, अगले अद्यतन के लिए आधे रास्ते) क्लाइंट और सर्वर स्थिति में परिवर्तित हो जाएं।

अपने सेटअप में घबराहट को कम करने के लिए एक और विचार: चूंकि आप "वर्तमान" और "अगले" निर्देशांक दोनों को प्रसारित करते हैं, इसलिए आप ऑब्जेक्ट के वेग की गणना कर सकते हैं। फिर, जब अपडेट लैग होता है, तो आप ऑब्जेक्ट को उसके गंतव्य (यानी "अगला" स्थिति) पर नहीं रोकते हैं, लेकिन उसे उसी वेग से आगे बढ़ाते रहते हैं। यदि आपकी वस्तुएं अपनी गति में अचानक बदलाव नहीं करती हैं, तो यह वास्तव में क्लाइंट पर गति की चिकनाई में सुधार करेगा।


यह पहले से ही ऐसा है, कि वस्तुओं को रोकना नहीं है, वे अगले अद्यतन प्राप्त होने तक आगे बढ़ना जारी रखते हैं। इसके अलावा, HTML कैनवास पर हार्डवेयर एक्सेलेरेशन का उपयोग करने से घबराना प्रभाव काफी कम हो जाता है। शायद मैं इतने लंबे समय तक उस चीज पर काम करने के बाद पागल हो गया हूं।
इवो ​​वेटजेल

यह काफी संभव है। यदि त्वरण को चालू करने से फ्रेम दर अधिक हो जाती है, तो सही समय पर अद्यतन जानकारी को संभालने की संभावना बढ़ जाती है।
बात नहीं

9

मैंने इस समस्या को हल किया है इससे पहले कि मैं "नेटवर्क शैडो" कहता हूं, कुछ सफलता के साथ। मुझे नहीं पता कि यह ऐसा कुछ है जो अन्य लोग करते हैं, लेकिन यह हमेशा मेरे लिए काम करता है।

प्रत्येक इकाई जो पूरे नेटवर्क में सिंक्रनाइज़ की जा रही है, एक अदृश्य नेटवर्क छाया इकाई है। जब नेटवर्क से कोई अपडेट आता है, तो आप छाया को उस स्थिति में सीधे उस स्थिति में भेज देते हैं, जहां नेटवर्क कहता है कि यह उस समय होना चाहिए, तब आप धीरे-धीरे स्थानीय दृश्यमान इकाई को समय के साथ छाया की ओर प्रक्षेपित करते हैं।

मैं अपने पिछले जवाब में इस दृष्टिकोण के बारे में विस्तार का एक बहुत कुछ शामिल यहाँ


हम्म, मैंने कुछ ऐसा किया है कि पहले के संस्करण में, फ्लोटिंग पॉइंट इंप्रेशन ने इसे कई बार खराब कर दिया था, मेरे पास अपडेट के लिए कुछ समय के लिए 300 मिलियन तक के बड़े बड़े दांव हैं, लेकिन शायद मैंने इसे गलत किया, मैंने इसे गलत किया। एक शॉट जब मुझे कुछ खाली समय मिल जाता है :)
इवो ​​वेटजेल

फ्लोटिंग पॉइंट प्रिसिजन वास्तव में इस पर नहीं आना चाहिए! क्या आपने स्टैकओवरफ्लो पर मेरा जुड़ा हुआ जवाब पढ़ा है? इसमें इस तरह की चीजों को लागू करने के सभी विवरण शामिल हैं।
मार्टिन

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.