प्रक्षेप किसी वस्तु की गति को सुचारू बनाने के लिए वास्तव में कैसे काम करता है?


10

मैंने पिछले 8 महीनों में कुछ इसी तरह के सवाल पूछे हैं या कोई वास्तविक खुशी नहीं है, इसलिए मैं सवाल को और सामान्य बनाने जा रहा हूं।

मेरे पास एक Android गेम है जो OpenGL ES 2.0 है। इसके भीतर मेरे पास निम्नलिखित गेम लूप है:

मेरा लूप एक निश्चित समय कदम सिद्धांत (dt = 1 / ticksPerSecond ) पर काम करता है

loops=0;

    while(System.currentTimeMillis() > nextGameTick && loops < maxFrameskip){

        updateLogic(dt);
        nextGameTick+=skipTicks;
        timeCorrection += (1000d/ticksPerSecond) % 1;
        nextGameTick+=timeCorrection;
        timeCorrection %=1;
        loops++;

    }

    render();   

मेरा अंतर्मन इस तरह काम करता है:

sprite.posX+=sprite.xVel*dt;
sprite.posXDrawAt=sprite.posX*width;

अब, सब कुछ बहुत काम करता है जैसा मैं चाहूंगा। मैं निर्दिष्ट कर सकता हूं कि मैं एक वस्तु को 2.5 सेकंड में एक निश्चित दूरी (स्क्रीन चौड़ाई कहना) पर ले जाना चाहता हूं और यह बस यही करेगा। इसके अलावा फ्रेम लंघन के कारण जो मैं अपने गेम लूप में अनुमति देता हूं, मैं इसे किसी भी डिवाइस पर कर सकता हूं और यह हमेशा 2.5 सेकंड लेगा।

मुसीबत

हालाँकि, समस्या यह है कि जब एक रेंडर फ्रेम स्केप, ग्राफिक हकलाना। यह बेहद कष्टप्रद है। यदि मैं फ़्रेम को छोड़ने की क्षमता को हटाता हूं, तो आप की तरह सब कुछ चिकना है, लेकिन विभिन्न उपकरणों पर अलग-अलग गति से चलेगा। तो यह एक विकल्प नहीं है।

मुझे अभी भी यकीन नहीं है कि फ्रेम क्यों खिसकता है, लेकिन मैं यह बताना चाहूंगा कि यह खराब प्रदर्शन से कोई लेना-देना नहीं है , मैंने कोड को ठीक 1 छोटे स्प्राइट पर ले लिया है और कोई तर्क नहीं है (आवश्यक तर्क के अलावा) स्प्राइट को स्थानांतरित करें) और मुझे अभी भी स्किप किए गए फ़्रेम मिलते हैं। और यह Google Nexus 10 टैबलेट पर है (और जैसा कि ऊपर उल्लेख किया गया है, मुझे वैसे भी उपकरणों के बीच गति को बनाए रखने के लिए फ्रेम स्किपिंग की आवश्यकता है)।

इसलिए, मेरे पास एकमात्र अन्य विकल्प इंटरपोलेशन (या एक्सट्रपलेशन) का उपयोग करना है, मैंने वहां पढ़ा हर लेख पढ़ा है, लेकिन किसी ने भी वास्तव में मुझे यह समझने में मदद नहीं की है कि यह कैसे काम करता है और मेरे सभी प्रयास विफल हो गए हैं।

एक विधि का उपयोग करके मैं चीजों को सुचारू रूप से चलाने में सक्षम था लेकिन यह असाध्य था क्योंकि इससे मेरी टक्कर गड़बड़ हो गई। मैं किसी भी समान विधि के साथ एक ही मुद्दे को दूर कर सकता हूं क्योंकि रेंडरिंग समय पर - (और भीतर कार्य किया गया है) को रेंडर किया गया है। इसलिए यदि Collision स्थिति को सही करता है (चरित्र अब दीवार के ठीक सामने खड़ा है), तो रेंडरर यह स्थिति बदल सकता है और इसे दीवार में खींच सकता है

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

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

संपादित करें

कुछ अतिरिक्त जानकारी - गेम लूप में उपयोग किए जाने वाले चर।

private long nextGameTick = System.currentTimeMillis();
//loop counter
private int loops;
//Amount of frames that we will allow app to skip before logic is affected
private final int maxFrameskip = 5;                         
//Game updates per second
final int ticksPerSecond = 60;
//Amount of time each update should take        
private final int skipTicks = (1000 / ticksPerSecond);
float dt = 1f/ticksPerSecond;
private double timeCorrection;

और पतन का कारण है ...................?
BungleBonce

1
कभी-कभी कहना असंभव है। यह एक समस्या को हल करने की कोशिश कर रहा है जब सब कुछ एक अच्छा सवाल होना चाहिए लगता है। कॉन्सिफ़ कोड स्निपेट, आपने जो प्रयास किया है, उसकी व्याख्या, शोध के प्रयास, और स्पष्ट रूप से यह बताना कि आपकी समस्या क्या है और आपको क्या जानना है।
जेसी दोर्से

मैं आपका अपमान नहीं कर रहा था, लेकिन कृपया एक भाग स्पष्ट करें। आप कहते हैं कि जब एक फ्रेम को छोड़ दिया जाता है तो ग्राफिक्स हकलाने लगता है। ऐसा लगता है कि एक स्पष्ट कथन (एक फ्रेम छूट गया है, ऐसा लगता है कि एक फ्रेम छूट गया है)। तो क्या आप स्किपिंग को बेहतर तरीके से समझा सकते हैं? क्या कुछ वियर होता है? यदि नहीं, तो यह एक असम्भव समस्या हो सकती है, क्योंकि फ्रैमर्ट डिप होने पर आपको सुचारू गति नहीं मिल सकती है।
सेठ बट्टिन

धन्यवाद, नोक्ट्रीन, यह वास्तव में मुझे परेशान करता है जब लोग स्पष्टीकरण को छोड़ने के बिना डाउनवोट करते हैं। @SethBattin, माफ करना, हाँ निश्चित रूप से, आप कर रहे हैं ठीक है, फ्रेम लंघन झटका खड़ी कर रहा है, फिर भी, किसी प्रकार की प्रक्षेप चाहिए इस सुलझा, जैसा कि मैंने ऊपर का कहना है, मैं कुछ मिला है (लेकिन सीमित) सफलता। अगर मैं गलत हूं, तो मुझे लगता है कि सवाल यह होगा कि मैं विभिन्न उपकरणों पर समान गति से आसानी से कैसे चल सकता हूं?
वनबॉनस

4
ध्यान से उन दस्तावेजों को फिर से पढ़ना। वे वास्तव में रेंडरिंग विधि में ऑब्जेक्ट के स्थान को संशोधित नहीं करते हैं। वे केवल अपनी अंतिम स्थिति के आधार पर विधि के स्पष्ट स्थान को संशोधित करते हैं और कितना समय बीत चुका है इसके आधार पर इसकी वर्तमान स्थिति।
अटैकिंगहोबो

जवाबों:


5

गति के सुचारू रूप से प्राप्त होने के लिए दो चीजें महत्वपूर्ण हैं, पहला यह है कि स्पष्ट रूप से आपको उस समय अपेक्षित स्थिति से मिलान करने की आवश्यकता है जिस समय फ्रेम उपयोगकर्ता को प्रस्तुत किया जाता है, दूसरा यह है कि आपको उपयोगकर्ता को फ्रेम प्रस्तुत करने की आवश्यकता है अपेक्षाकृत निश्चित अंतराल पर। T + 10ms पर एक फ्रेम प्रस्तुत करना, फिर T + 30ms पर एक और, फिर T + 40ms पर एक और, उपयोगकर्ता को न्याय करने के लिए दिखाई देगा, भले ही वास्तव में उन समय के लिए जो दिखाया गया है वह सिमुलेशन के अनुसार सही हो।

आपके मुख्य लूप में यह सुनिश्चित करने के लिए कि आपको केवल नियमित अंतराल पर रेंडर करने के लिए किसी भी गेटिंग तंत्र की कमी है। तो कभी-कभी आप रेंडरर्स के बीच 3 अपडेट कर सकते हैं, कभी-कभी आप 4 कर सकते हैं। मूल रूप से आपका लूप जितनी बार संभव हो, उतनी ही जल्दी रेंडर करेगा, जैसे ही आपने वर्तमान समय के सामने सिमुलेशन स्टेट को पुश करने के लिए पर्याप्त समय दिया होगा, आप फिर उस अवस्था को प्रस्तुत करें। लेकिन किसी भी परिवर्तनशीलता को अपडेट या रेंडर करने में कितना समय लगता है, और फ़्रेम के बीच का अंतराल भी अलग-अलग होगा। आपको अपने सिमुलेशन के लिए एक निश्चित टाइमस्टेप मिला है, लेकिन आपके प्रतिपादन के लिए एक चर टाइमस्टेप।

आपके रेंडर से ठीक पहले आपको जो चाहिए, वह है, यह सुनिश्चित करना कि आप केवल रेंडर अंतराल की शुरुआत में ही रेंडर करना शुरू कर दें। आदर्श रूप से यह अनुकूली होना चाहिए: यदि आपने अपडेट / रेंडर करने के लिए बहुत लंबा समय लिया है और अंतराल की शुरुआत पहले ही बीत चुकी है, तो आपको तुरंत रेंडर करना चाहिए, लेकिन अंतराल की लंबाई भी बढ़ाएं, जब तक कि आप लगातार रेंडर और अपडेट नहीं कर सकते हैं और अभी भी प्राप्त कर सकते हैं अंतराल से पहले अगले रेंडर समाप्त हो गया है। यदि आपके पास बहुत समय है, तो आप धीरे-धीरे फिर से रेंडर करने के लिए अंतराल (यानी फ्रेम दर में वृद्धि) को कम कर सकते हैं।

लेकिन, और यहां किकर है, यदि आपने यह पता लगाने के तुरंत बाद फ्रेम को रेंडर नहीं किया है कि सिमुलेशन स्टेट को "अब" में अपडेट किया गया है, तो आप लौकिक अलियासिंग का परिचय देते हैं। उपयोगकर्ता को प्रस्तुत किया जा रहा फ्रेम थोड़ा गलत समय पर प्रस्तुत किया जा रहा है, और यह अपने आप में एक हकलाना की तरह महसूस होगा।

यह आपके द्वारा पढ़े गए लेखों में उल्लिखित "आंशिक टाइमस्टेप" का कारण है। यह एक अच्छे कारण के लिए है, और ऐसा इसलिए है क्योंकि जब तक आप अपनी भौतिकी टाइमस्टेप को अपने निश्चित रेंडरिंग टाइमस्टेप के कुछ निश्चित इंटीग्रल मल्टीपल में ठीक नहीं करते हैं, आप बस सही समय पर फ्रेम प्रस्तुत नहीं कर सकते हैं। आप उन्हें या तो बहुत जल्दी, या बहुत देर से पेश करते हैं। एक निश्चित रेंडरिंग दर प्राप्त करने का एकमात्र तरीका और अभी भी कुछ ऐसा है जो शारीरिक रूप से सही है, यह स्वीकार करना है कि जिस समय रेंडरिंग अंतराल चारों ओर आता है, आप अपने निश्चित भौतिकी टाइमस्टेप्स में से दो के बीच मध्य-मार्ग की संभावना करेंगे। लेकिन इसका मतलब यह नहीं है कि वस्तुओं को प्रतिपादन के दौरान संशोधित किया जाता है, बस यह कि अस्थायी रूप से यह स्थापित करना है कि ऑब्जेक्ट कहाँ हैं ताकि यह उन्हें उस जगह के बीच कहीं प्रस्तुत कर सके जहां वे पहले थे और जहां वे अपडेट के बाद हैं। यह महत्वपूर्ण है - प्रतिपादन के लिए कभी भी विश्व की स्थिति को न बदलें, केवल अपडेट से विश्व स्थिति को बदलना चाहिए।

इसलिए इसे स्यूडोकोड लूप में डालने के लिए, मुझे लगता है कि आपको कुछ और चाहिए जैसे:

InitialiseWorldState();

previousTime = currentTime = 0.0;
renderInterval = 1.0 / 60.0; //A nice high starting interval

subFrameProportion = 1.0; //100% currentFrame, 0% previousFrame

while (true)
{
    frameStart = ActualTime();

    //Render the world state as if it was some proportion 
    // between previousTime and currentTime
    // E.g. if subFrameProportion is 0.5, previousTime is 0.1 and 
    // currentTime is 0.2, then we actually want to render the state
    // as it would be at time 0.15. We'd do that by interpolating 
    // between movingObject.previousPosition and movingObject.currentPosition
    // with a lerp parameter of 0.5
    Render(subFrameProportion); 

    //Check we've not taken too long and missed our render interval
    frameTime = ActualTime() - frameStart;
    if (frameTime > renderInterval)
    {
        renderInterval = frameTime * 1.2f; //Give us a more reasonable render interval that we actually have a chance of hitting
    }

    expectedFrameEnd = frameStart + renderInterval;

    //Loop until it's time to render the next frame
    while (ActualTime() < expectedFrameEnd)
    {
        //step the simulation forward until it has moved just beyond the frame end
        if (previousTime < expectedFrameEnd) &&
            currentTime >= expectedFrameEnd)
        {
            previousTime = currentTime;

            Update();
            currentTime += fixedTimeStep;

            //After the update, all objects will be in the position they should be for
            // currentTime, **but** they also need to remember where they were before,
            // so that the rendering can draw them somewhere between previousTime and
            //  currentTime

            //Check again we've not taken too long and missed our render interval
            frameTime = ActualTime() - frameStart;
            if (frameTime > renderInterval)
            {
                renderInterval = frameTime * 1.2f; //Give us a more reasonable render interval that we actually have a chance of hitting
                expectedFrameEnd = frameStart + renderInterval
            }
        }
        else
        {
            //We've brought the simulation to just after the next time
            // we expect to render, so we just want to wait.
            // Ideally sleep or spin in a tight loop while waiting.
            timeTillFrameEnd = expectedFrameEnd - ActualTime();
            sleep(timeTillFrameEnd);
        }
    }

    //How far between update timesteps (i.e. previousTime and currentTime)
    // will we be at the end of the frame when we start the next render?
    subFrameProportion = (expectedFrameEnd - previousTime) / (currentTime - previousTime);
}

इसके लिए सभी वस्तुओं को अद्यतन करने के लिए, जहां वे पहले थे और अब वे हैं, का ज्ञान संरक्षित करने की आवश्यकता है, ताकि प्रतिपादन इसका उपयोग कर सके कि वस्तु कहां है।

class MovingObject
{
    Vector velocity;
    Vector previousPosition;
    Vector currentPosition;

    Initialise(startPosition, startVelocity)
    {
        currentPosition = startPosition; // position at time 0
        velocity = startVelocity;
        //ignore previousPosition because we should never render before time 0
    }

    Update()
    {
        previousPosition = currentPosition;
        currentPosition += velocity * fixedTimeStep;
    }

    Render(subFrameProportion)
    {
        Vector actualPosition = 
            Lerp(previousPosition, currentPosition, subFrameProportion);
        RenderAt(actualPosition);
    }
}

और चलो मिलीसेकंड में एक टाइमलाइन बनाते हैं, कहते हैं कि रेंडरिंग में 3ms लगते हैं, अपडेट करने में 1ms लगते हैं, आपका अपडेट टाइम-स्टेप 5ms पर तय होता है, और आपका रेंडर टाइमस्टेप शुरू होता है (और रहता है) 16ms [60Hz]।

0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33
R0          U5  U10 U15 U20 W16                                 R16         U25 U30 U35 W32                                 R32
  1. पहले हम समय पर आरंभ करते हैं 0 (इसलिए वर्तमान समय = 0)
  2. हम 1.0 (100% वर्तमान समय) के अनुपात के साथ प्रस्तुत करते हैं, जो दुनिया को 0 पर आकर्षित करेगा
  3. जब वह पूरा हो जाता है, तो वास्तविक समय 3 है, और हम फ्रेम को 16 तक समाप्त होने की उम्मीद नहीं करते हैं, इसलिए हमें कुछ अपडेट चलाने की आवश्यकता है
  4. T + 3: हम 0 से 5 तक अपडेट करते हैं (इसलिए बाद में currentTime = 5, पिछले समय = 0)
  5. T + 4: अभी भी फ्रेम समाप्त होने से पहले, इसलिए हम 5 से 10 तक अपडेट करते हैं
  6. T + 5: अभी भी फ्रेम समाप्त होने से पहले, इसलिए हम 10 से 15 तक अपडेट करते हैं
  7. T + 6: अभी भी फ्रेम समाप्त होने से पहले, इसलिए हम 15 से 20 तक अपडेट करते हैं
  8. T + 7: अभी भी फ्रेम समाप्त होने से पहले, लेकिन वर्तमान समय सीमा के अंत से परे है। हम आगे कोई अनुकरण नहीं करना चाहते क्योंकि ऐसा करने से हमें उस समय से परे धकेल दिया जाएगा जब हम अगली बार प्रस्तुत करना चाहते हैं। इसके बजाय हम अगले रेंडर अंतराल (16) के लिए चुपचाप प्रतीक्षा करते हैं
  9. T + 16: यह फिर से प्रस्तुत करने का समय है। पिछला समय 15 है, वर्तमान समय 20 है। इसलिए यदि हम T + 16 पर रेंडर करना चाहते हैं, तो हम 5ms लंबे टाइमस्टेप के माध्यम से 1ms हैं। तो हम फ्रेम (अनुपात = 0.2) के माध्यम से 20% रास्ते हैं। जब हम रेंडर करते हैं, तो हम वस्तुओं को उनकी पिछली स्थिति और उनकी वर्तमान स्थिति के बीच 20% का रास्ता बनाते हैं।
  10. 3. वापस लूप करें और अनिश्चित काल तक जारी रखें।

समय से बहुत आगे अनुकरण करने के बारे में यहां एक और बारीकियों है, जिसका अर्थ है कि उपयोगकर्ता के इनपुट को अनदेखा किया जा सकता है, भले ही वे फ्रेम वास्तव में प्रदान किए जाने से पहले हुए थे, लेकिन इसके बारे में चिंता न करें जब तक आप आश्वस्त न हों कि लूप आसानी से अनुकरण कर रहा है।


नायब: दो तरीकों से स्यूडोकोड कमजोर है। सबसे पहले यह मृत्यु-सर्पिल मामले को नहीं पकड़ता है (इसे अपडेट करने के लिए तय समय सीमा से अधिक समय लगता है, जिसका अर्थ है कि अनुकरण कभी भी पीछे हो जाता है, प्रभावी रूप से एक अनंत लूप), दूसरा रेंडरइन्टरवल फिर कभी छोटा नहीं होता। व्यवहार में आप रेंडर इन्टरवल को तुरंत बढ़ाना चाहते हैं, लेकिन फिर समय के साथ इसे धीरे-धीरे कम कर सकते हैं जितना कि आप वास्तविक फ्रेम समय की कुछ सहनशीलता के भीतर कर सकते हैं। अन्यथा एक बुरा / लंबा अपडेट आपको हमेशा के लिए कम फ्रैमरेट से परेशान कर देगा।
MrCranky

इस @MrCranky के लिए धन्यवाद, वास्तव में, मैं अपने पाश में 'सीमा' प्रदान करने के तरीके पर उम्र के लिए संघर्ष कर रहा हूं! बस यह कैसे करना है यह काम नहीं कर सकता है और आश्चर्य है कि अगर यह मुद्दों में से एक हो सकता है। मैं इस के माध्यम से एक उचित पढ़ा होगा और अपने सुझाव एक कोशिश दे, वापस रिपोर्ट करेंगे! धन्यवाद फिर से :-)
BungleBonce

धन्यवाद @MrCranky, ठीक है, मैंने आपके उत्तर को पढ़ लिया है और फिर से पढ़ा है, लेकिन मैं इसे समझ नहीं पा रहा हूं :-( मैंने इसे लागू करने की कोशिश की, लेकिन इसने मुझे सिर्फ एक रिक्त स्क्रीन दे दी। वास्तव में इससे जूझ रहा हूं। मेरी चलती वस्तुओं की पिछली और वर्तमान स्थिति से संबंधित है; इसके अलावा, लाइन के बारे में क्या "currentFrame = Update ();" - मुझे यह लाइन नहीं मिलती है, क्या इसका मतलब कॉल अपडेट () है; जैसा कि मैं देख नहीं सकता हूं वरना मैं अपडेट कॉल कर रहा हूं? या इसका मतलब सिर्फ वर्तमान मूल्य (स्थिति) को नए मूल्य पर सेट करना है? आपकी मदद के लिए फिर से धन्यवाद !!
BungleBonce

हाँ, प्रभावी ढंग से। कारण है कि मैं पिछलेFrame और currentFrame में अद्यतन और प्रारंभविकरण से वापसी मानों के रूप में डालता हूं क्योंकि दुनिया को आकर्षित करने के लिए रेंडरिंग की अनुमति देना क्योंकि यह दो निश्चित अपडेट चरणों के बीच का हिस्सा है, आपको न केवल प्रत्येक की वर्तमान स्थिति की आवश्यकता है ऑब्जेक्ट जिसे आप खींचना चाहते हैं, लेकिन उनकी पिछली स्थिति भी। आप प्रत्येक वस्तु को आंतरिक रूप से दोनों मूल्यों को बचा सकते हैं, जो कि अस्पष्ट है।
MrCranky

लेकिन यह वास्तुशिल्प चीजों के लिए भी संभव है (लेकिन बहुत कठिन है) ताकि समय पर दुनिया की वर्तमान स्थिति का प्रतिनिधित्व करने के लिए आवश्यक सभी राज्य जानकारी एक ही वस्तु के तहत आयोजित हो। वैचारिक रूप से यह बहुत साफ है कि सिस्टम में कौन सी जानकारी है, यह समझाते हुए कि आप एक अद्यतन चरण द्वारा निर्मित फ्रेम स्थिति का इलाज कर सकते हैं, और पिछले फ्रेम को इधर-उधर रखना केवल उन फ्रेम राज्य वस्तुओं में से एक को बनाए रखने के बारे में है। हालाँकि मैं उत्तर को फिर से लिख सकता हूँ जैसे आप वास्तव में इसे लागू करेंगे।
MrCranky

3

हर कोई जो आपको बता रहा है वह सही है। अपने रेंडर लॉजिक में अपने स्प्राइट की सिमुलेशन स्थिति को कभी भी अपडेट न करें।

इसे इस तरह से सोचो, आपके स्प्राइट में 2 स्थान हैं; जहां सिमुलेशन कहता है कि वह अंतिम सिमुलेशन अपडेट के रूप में है, और जहां स्प्राइट का प्रतिपादन किया गया है। वे दो पूरी तरह से अलग निर्देशांक हैं।

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

इसके अलावा, आपको अच्छी समझ है। उम्मीद है की यह मदद करेगा।


उत्कृष्ट @WilliamMorrison - इसकी पुष्टि करने के लिए धन्यवाद, मैं वास्तव में कभी भी 100% निश्चित नहीं था कि यह मामला था, अब मुझे लगता है कि मैं इस काम को कुछ हद तक प्राप्त करने के रास्ते पर हूँ - चीयर्स!
जंगलबोनसे

बस जिज्ञासु @WilliamMorrison, इन दूर-दूर निर्देशांकों का उपयोग करते हुए, कोई व्यक्ति अन्य वस्तुओं में 'एम्बेडेड' या 'ऊपर' के रूप में एम्बेडेड होने की समस्या को कैसे कम करेगा - स्पष्ट उदाहरण, 2 डी गेम में ठोस वस्तुएं। क्या आपको अपने टक्कर कोड को रेंडर समय पर भी चलाना होगा?
वनबोनसे

मेरे खेल में हां, यही मैं करता हूं। कृपया मुझसे बेहतर रहें, ऐसा न करें, यह सबसे अच्छा समाधान नहीं है। यह कोड को उस तर्क के साथ प्रस्तुत करता है जिसे वह उपयोग नहीं कर रहा है, और निरर्थक टक्कर का पता लगाने पर सीपीयू को बर्बाद कर देगा। दूसरे से अंतिम स्थान और वर्तमान स्थिति के बीच अंतर करना बेहतर होगा। यह समस्या को हल करता है क्योंकि आप खराब स्थिति में नहीं जा रहे हैं, लेकिन चीजों को जटिल करते हैं क्योंकि आप सिमुलेशन के पीछे एक कदम बढ़ा रहे हैं। आईडी आपकी राय सुनना पसंद करती है, जो आप ले जाते हैं, और आपके अनुभव।
विलियम मॉरिसन

हाँ यह हल करने के लिए एक मुश्किल समस्या है। मैंने इस बारे में एक अलग सवाल पूछा है यहाँ gamedev.stackexchange.com/questions/83230/… यदि आप इस पर नज़र रखना चाहते हैं या कुछ योगदान करना चाहते हैं। अब, आपने अपनी टिप्पणी में क्या सुझाव दिया है, क्या मैं यह पहले से नहीं कर रहा हूं? (पिछले और वर्तमान फ्रेम के बीच इंटरपोलिंग)?
जंगल बोससे

काफी नहीं। आप वास्तव में अभी एक्सट्रपलेशन कर रहे हैं। आप सिमुलेशन से सबसे वर्तमान डेटा लेते हैं, और अंशकालिक टाइमस्टेप के बाद वह डेटा कैसा दिखता है, इसे एक्सट्रपलेशन करते हैं। मैं आपको पिछले सिमुलेशन स्थिति और इसके बजाय रेंडर करने के लिए आंशिक टाइमस्टेप द्वारा वर्तमान सिमुलेशन स्थिति के बीच इंटरपोलेट करने का सुझाव दे रहा हूं। 1 टाइमस्टेप द्वारा सिमुलेशन के पीछे रेंडरिंग होगा। यह सुनिश्चित करता है कि आप उस स्थिति में कभी भी किसी वस्तु को प्रस्तुत नहीं करेंगे, जो अनुकरण को मान्य नहीं करता है (यानी जब तक कि अनुकृति विफल नहीं हो जाती। एक प्रक्षेप्य दीवार में दिखाई नहीं देगा।)
विलियम मॉरिसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.