फ़्रेम स्वतंत्र आंदोलन


11

मैंने आंदोलन पर दो अन्य सूत्र यहां पढ़े हैं: समय आधारित आंदोलन बनाम फ्रेम दर आधारित आंदोलन? , और मुझे एक निश्चित या चर समय चरण का उपयोग कब करना चाहिए?

लेकिन मुझे लगता है कि मुझे फ्रेम इंडिपेंडेंट मूवमेंट की बुनियादी समझ की कमी है क्योंकि मुझे समझ नहीं आ रहा है कि दोनों में से कौन सा सूत्र बात कर रहा है।

मैं आलसी के एसडीएल ट्यूटोरियल के साथ अनुसरण कर रहा हूं और स्वतंत्र पाठ के फ्रेम पर आया हूं। http://lazyfoo.net/SDL_tutorials/lesson32/index.php

मुझे यकीन नहीं है कि कोड का आंदोलन भाग क्या कहने की कोशिश कर रहा है, लेकिन मुझे लगता है कि यह यह है (कृपया मुझे सही करें अगर मैं गलत हूं): स्वतंत्र आंदोलन को फ्रेम करने के लिए, हमें यह पता लगाना होगा कि कोई वस्तु कितनी दूर है ( उदा। स्प्राइट) एक निश्चित समय सीमा के भीतर चलता है, उदाहरण के लिए 1 सेकंड। यदि डॉट 200 पिक्सेल प्रति सेकंड की गति से चलती है, तो मुझे यह गणना करने की आवश्यकता है कि यह 200 सेकंड में गुणा करके उस सेकंड के 1/1000 से कितने गुणा बढ़ जाता है।

क्या वह सही है? सबक कहता है:

"सेकंड में अंतिम फ्रेम के बाद से पिक्सेल प्रति सेकंड * समय में वेग। इसलिए यदि कार्यक्रम 200 फ्रेम प्रति सेकंड पर चलता है: 200 pps * 1/200 सेकंड = 1 पिक्सेल"

लेकिन ... मुझे लगा कि हम एक सेकंड के 1/1000 वें द्वारा 200 pps गुणा कर रहे हैं। प्रति सेकंड फ़्रेम के साथ यह व्यवसाय क्या है?

मैं सराहना करता हूँ अगर कोई मुझे थोड़ा और विस्तृत विवरण दे सकता है कि स्वतंत्र आंदोलन कैसे काम करता है।

धन्यवाद।

अलावा:

SDL_Rect posRect;
posRect.x = 0;
posRect.y = 0;

float y, yVel;
y = 0;
yVel = 0;

Uint32 startTicks = SDL_GetTicks();

bool quit = false;
SDL_Event gEvent;

while ( quit == false )
{
    while ( SDL_PollEvent( &gEvent ) )
    {
        if ( gEvent.type == SDL_QUIT )
            quit = true;
    }

    if ( y <= 580 )
    {
        yVel += DOT_VEL;
        y += (yVel * (SDL_GetTicks() - startTicks)/1000.f);
        posRect.y = (int)y;
    }

    startTicks = SDL_GetTicks();
    SDL_BlitSurface( bg, NULL, screen, NULL );
    SDL_BlitSurface( dot, NULL, screen, &posRect );
    SDL_Flip( screen );
}

यह कोड है जो स्क्रीन के नीचे एक डॉट को स्थानांतरित करता है। मुझे लगता है कि मेरे पास अब तक सब कुछ सही है। यह स्क्रीन को नीचे ले जाता है, लेकिन एक अजीब सी चीज़ होती है जो कि मैं समझा नहीं सकता। जब यह उस y- मान से अधिक हो जाता है तो डॉट को y = 580 पर रहना चाहिए। हालाँकि, हर बार जब मैं प्रोग्राम चलाता हूं, तो डॉट एक अलग स्थान पर समाप्त हो जाएगा, जिसका अर्थ 580 से थोड़ा अधिक है, इसलिए डॉट स्क्रीन से आधी या आधी से अधिक है (डॉट 20 पिक्सेल है, स्क्रीन आयाम 800x600)। अगर मैं प्रोग्राम के टाइटल-बार को क्लिक और होल्ड करने जैसा कुछ करता हूं, और फिर रिलीज़ होता है, तो डॉट स्क्रीन से गायब हो जाता है। यह हर बार परिवर्तनशील कैसे होता है? जैसा कि टाइटलर समस्या के लिए मुझे लगता है कि यह इसलिए है क्योंकि जब मैं टाइटलबार को पकड़ता हूं, तो टाइमर अभी भी चल रहा है, और समय बीतने पर बड़ा हो जाता है, एक बड़ी दूरी के परिणामस्वरूप डॉट अगले फ्रेम में चलती है। क्या वह सही है?


आपका जोड़ वास्तव में एक और सवाल है। आपको इसे अपने मौजूदा में जोड़ने के बजाय इसे दूसरा प्रश्न बनाना चाहिए। हालांकि इसका आसानी से जवाब दिया जा सकता है: बस y- मूवमेंट की गणना करें, जैसे। yMovement = (yVel * (SDL_GetTicks() - startTicks)/1000.f);फिर करते हैं:if(y + yMovement <= 580){ y += yMovement; } else { y = 580; }
bummzack

जवाबों:


10

नोट: सभी भिन्नों को तैरने के लिए बनाया गया है।

फ्रेम इंडिपेंडेंट मूवमेंट ऑफ मूवमेंट ऑफ ऑफ टाइम से काम करता है। आपको उस समय की राशि मिलती है जो अंतिम फ्रेम के बाद से खर्च होती है (इसलिए यदि एक सेकंड में 60 फ्रेम हैं, तो प्रत्येक फ्रेम में 1.0 / 60.0 सेकंड लगते हैं, यदि सभी फ़्रेमों ने समान समय लिया हो) और पता करें कि कितना आंदोलन है में अनुवाद करता है।

यदि आप चाहते हैं कि आपकी इकाई एक निश्चित समय के लिए एक निश्चित मात्रा में स्थान ले जाए (हम हर सेकंड के लिए 100 पिक्सेल कहेंगे) तो आप यह पता लगा सकते हैं कि प्रति चक्कर की मात्रा को बढ़ाकर आपको प्रति फ्रेम कितने पिक्सेल चलना चाहिए। दूसरी (100 पिक्सेल) सेकंड के समय (1.0 / 60.0) में यह पता लगाने के लिए कि वर्तमान फ्रेम में कितना मूवमेंट होना चाहिए।

यह पता लगाकर काम करता है कि समय की मात्रा और गति जो किसी इकाई के साथ परिभाषित है (सेकंड या मिलीसेकंड बेहतर हैं) का उपयोग करके आपको प्रति फ्रेम कितना आंदोलन करना चाहिए। तो आपकी गणना इस तरह दिख सकती है:movementPerSecond * (timeElapsedInMilliseconds / 1000.0)

मुझे उम्मीद है कि आप के लिए किसी तरह की समझ में आया।

मैं अपने आदमी को हर सेकंड में 200 पिक्सेल दाईं ओर ले जाना चाहता हूं। यदि पिछले फ्रेम के बाद वर्तमान फ़्रेम 50 मिलीसेकंड चलाया जाता है, तो मुझे अपने आदमी को पहले निर्दिष्ट गति (जो कि 200 पिक्सेल थी) का एक अंश स्थानांतरित करना चाहिए। मुझे उसे दूरी के ५० / १००० वें स्थान पर ले जाना चाहिए क्योंकि केवल १ / २० वीं (५०/१००० = १/२०) समय बीत चुका है। इसलिए यह समझ में आता है कि केवल उसे 10 पिक्सल हिलाने के लिए (यदि 19 और फ्रेम होते हैं, 50 मिलीसेकंड एक दूसरे के अलावा, तो उस सेकंड में आंदोलन की कुल मात्रा 200 पिक्सेल होगी, जो राशि हम चाहते थे)।

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

फ्रेम प्रति सेकंड: यह फ्रेम की मात्रा है जो प्रति सेकंड होती है। आमतौर पर एक फ्रेम दर या तो खेल को कितनी बार खींचा जाता है / एक दूसरे को प्रस्तुत किया जाता है या कितनी बार गेम लूप को एक सेकंड में पूरा किया जाता है।

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


आपके द्वारा दिए गए उदाहरण में, 50 मिलीसेकंड प्रत्येक फ्रेम के लिए समय है, सही है? और इसकी गणना 1000 / FPS द्वारा की गई थी? और इसलिए प्रत्येक फ्रेम बनाने के लिए आपको जो मूवमेंट करना पड़ता है वह प्रति सेकंड पिक्सल * 50/1000 है?
झींगा क्रैकर्स

हम्म, मुझे एहसास हुआ कि प्रत्येक समय सीमा के लिए मिलीसेकंड शायद चर होगा, है ना? GetTicks () - startTicks की तरह कुछ हमेशा अलग और स्थिर नहीं होगा।
झींगा क्रैकर्स

@ विकल्प: यदि आप "पिक्सेल प्रति सेकंड" में दूरी निर्दिष्ट करते हैं तो आप मिलीसेकंड का उपयोग नहीं कर सकते ... यह 1.0 / 60.0 नहीं 1000/60 होना चाहिए जिसके परिणामस्वरूप पूरी तरह से कुछ अलग होगा।
bummzack

@SrimpCrackers हाँ, बीता हुआ समय बदल जाता है। एक पुराने पीसी की कल्पना करें जो 60 एफपीएस रेंडर करने में सक्षम नहीं है। आप अभी भी चाहते हैं कि गेम ऐसी मशीन पर समान गति (लेकिन समान एफपीएस नहीं) पर चले।
bummzack

हां, तो आलसी ट्यूटोरियल में, डेल्टिक्स में 1000 का मतलब क्या है / 1000.f? एफपीएस? 1000 मिलीसेकंड? मैं अभी थोड़ा उलझन में हूं। ऐसा लगता है कि प्रत्येक फ्रेम के लिए आवश्यक समय का निर्धारण करने में एफपीएस आवश्यक है, लेकिन यह वास्तव में आंदोलन में गणना नहीं करता है।
झींगा पटाखे

7

फ्रेम डायनेमिक्स में (उदाहरण के लिए) एक इकाई को ले जाने वाला कोड इस तरह दिखेगा:

x = x + speedPerFrame

यदि आप फ्रेम-स्वतंत्र होना चाहते हैं, तो यह इस तरह दिख सकता है:

x = x + speedPerSecond * secondsElapsedSinceLastFrame

धन्यवाद, यह समझ में आता है। मेरे ऊपर एक और सवाल है।
ShrimpCrackers

1

अतिरिक्त प्रश्न के संबंध में।

जब आप इसे स्थानांतरित करते हैं तो आपका बिंदु हर बार अलग-अलग स्थानों पर रुकता है क्योंकि आप सीमा (y> 580) की जांच नहीं करते हैं। आप केवल इसके पिछले 580 के अपडेट के बाद इसे अपडेट करना बंद कर देंगे।

आखिरी फ्रेम पर, इससे पहले कि आप 580 पार कर सकते हैं आप 579 से शुरू हो सकते हैं या आप 570 पर हो सकते हैं या आप 100 पर हो सकते हैं। आप अंतिम पिक्सेल को निष्पादित करने में कितना समय ले सकते हैं, इसके आधार पर आप 1 पिक्सेल आगे या 1000 कदम रख सकते हैं।

बस अपनी IF स्थिति को कुछ इस तरह बदलें और आप ठीक रहें।

if ( y <= 580 )
{
    yVel += DOT_VEL;
    y += (yVel * (SDL_GetTicks() - startTicks)/1000.f);
    if( y > 580 )
    {
        y = 580;
    }
    posRect.y = (int)y;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.