खेलों में समय उल्टा तंत्र


10

मैं इस बारे में सोच रहा हूं कि आमतौर पर खेलों में हेरफेर करने वाले तंत्र को किस तरह से डिजाइन किया जाता है। मैं विशेष रूप से समय उलटने (नवीनतम SSX या फारस के राजकुमार की तरह) में दिलचस्पी रखता हूं।

खेल एक 2 डी शीर्ष नीचे शूटर है।

मैं जिस तंत्र को डिजाइन / कार्यान्वित करने की कोशिश कर रहा हूं, उसकी निम्नलिखित आवश्यकताएं हैं:

1) खिलाड़ी चरित्र के अलावा संस्थाओं के कार्य पूरी तरह से निर्धारक हैं।

  • एक इकाई जो कार्रवाई करती है, वह स्क्रीन पर स्तर शुरू होने और / या खिलाड़ी की स्थिति के बाद से फ़्रेम पर आधारित होती है
  • स्तर के दौरान निर्धारित समय पर संस्थाओं को स्थान दिया जाता है।

2) वास्तविक समय में उलट-पलट कर समय उल्टा काम करता है।

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

उदहारण के लिए:

फ्रेम्स 0-50: प्लेयर इस समय में 20 यूनिट फाउन्ड करता है। फ्रेम 1 पर दुश्मन 1 बार घूमता है 20 दुश्मन 1 मूव्स फ्रेम के दौरान 10 यूनिट बचे, 30-40 प्लेयर फ्रेम पर गोली चलाता है। बुलेट 45 बुलेट 5 फॉवर्ड (45-50) में सफर करता है और एनल्स 1 को मारता है फ्रेम 50

इसे उलटने से वास्तविक समय में वापस चला जाएगा: खिलाड़ी इस समय 20 इकाइयों को पीछे ले जाता है। शत्रु 1 फ्रेम पर घूमता है 50 बुलेट फ्रेम में 50 बुलेट पीछे की ओर 5 गोली चलती है और गायब हो जाती है (50-45) शत्रु चालें 10 (40-30) को छोड़ देती हैं। फ्रेम 20।

बस आंदोलन को देखते हुए मुझे इस बारे में कुछ विचार थे कि इसे कैसे प्राप्त किया जाए, मैंने एक ऐसे इंटरफ़ेस के बारे में सोचा, जो उस समय के लिए व्यवहार को बदल रहा था या आगे बढ़ा रहा था। ऐसा कुछ करने के बजाय:

void update()
{
    movement += new Vector(0,5);
}

मैं ऐसा कुछ करूंगा:

public interface movement()
{
    public void move(Vector v, Entity e);
}

public class advance() implements movement
{
    public void move(Vector v, Entity e)
    {
            e.location += v;
    }
}


public class reverse() implements movement
{
    public void move(Vector v, Entity e)
    { 
        e.location -= v;
    }
}

public void update()
{
    moveLogic.move(new vector(5,0));
}

हालांकि मुझे एहसास हुआ कि यह इष्टतम प्रदर्शन बुद्धिमान नहीं होगा और जल्दी से और अधिक अग्रिम कार्यों के लिए जटिल हो जाएगा (जैसे घुमावदार पथों के साथ चिकनी आंदोलन)।


1
मैंने यह सब नहीं देखा है (यूट्यूब अस्थिर कैम, 1.5 घंटे) , लेकिन शायद जोनाथन ब्लो के कुछ विचारों ने उनके खेल में काम किया है।
MichaelHouse

के संभावित डुप्लिकेट gamedev.stackexchange.com/questions/15251/...
Hackworth

जवाबों:


9

आप कमांड पैटर्न पर एक नज़र डालना चाहते हैं ।

मूल रूप से प्रत्येक प्रतिवर्ती कार्रवाई जो आपकी संस्थाएं करती हैं, उन्हें कमांड ऑब्जेक्ट के रूप में लागू किया जाता है। उन सभी वस्तुओं को कम से कम 2 तरीकों से लागू किया जाता है: निष्पादित () और पूर्ववत करें (), इसके अलावा जो कुछ भी आपकी आवश्यकता है, जैसे सही समय के लिए समय टिकट संपत्ति।

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

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

अधिक गेम डिज़ाइन शेंनिगन के लिए, प्रत्येक इकाई को अपने स्टैक पर अपने कार्यों को संग्रहीत करने दें, ताकि आप उन्हें एक-दूसरे से स्वतंत्र रूप से पूर्ववत / फिर से कर सकें।

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


2
ध्यान दें कि एक खेल में क्रियाओं की प्रतिवर्तीता बहुत ही मार्मिक चीज हो सकती है, क्योंकि फ्लोटिंग-पॉइंट सटीक मुद्दों, चर टाइमस्टेप्स, आदि; यह उस स्थिति को बचाने के लिए ज्यादातर स्थितियों में इसका पुनर्निर्माण करने की तुलना में अधिक सुरक्षित है।
स्टीवन स्टैडनिक

@StevenStadnicki हो सकता है, लेकिन यह निश्चित रूप से संभव है। मेरे सिर के ऊपर, C & C जनरल्स इसे इस तरह करते हैं। इसमें 8 खिलाड़ियों तक के घंटे-लम्बे रिप्ले होते हैं, सबसे कम में कुछ सौ केबी में वजन होता है, और यह सबसे अधिक अनुमान है कि यदि सभी आरटीएस गेम अपने मल्टीप्लेयर नहीं करते हैं: तो आप संभावित सैकड़ों के साथ पूर्ण गेम राज्य को संचारित नहीं कर सकते हैं। इकाइयों के हर फ्रेम, आपको इंजन को अपडेट करने देना होगा। तो हाँ, यह निश्चित रूप से व्यवहार्य है।
हैकवर्थ

3
रिप्ले रिवाइंड से एक बहुत अलग बात है, क्योंकि संचालन जो लगातार प्रतिलिपि प्रस्तुत करने योग्य फॉर्वर्ड हैं (उदाहरण के लिए, फ्रेम n, x_n पर स्थिति खोजना, x_0 = 0 से शुरू करके और प्रत्येक चरण के लिए डेल्टास v_n को जोड़ना जरूरी नहीं है कि पीछे की ओर प्रतिलिपि प्रस्तुत करने योग्य हो। ; (x + v_n) -v_n फ्लोटिंग-पॉइंट मैथ्स में लगातार बराबर x नहीं होता है। और यह कहना आसान है कि 'इसके आस-पास काम करें' लेकिन आप संभावित रूप से एक पूर्ण ओवरहाल के बारे में बात कर रहे हैं, जिसमें कई बाहरी पुस्तकालयों का उपयोग नहीं किया जा सकता है।
स्टीवन स्टडनिक

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

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

1

आप मेमेंटो पैटर्न पर एक नज़र डाल सकते हैं; इसका प्राथमिक उद्देश्य वस्तु स्थिति को वापस लाकर पूर्ववत / पुनः संचालन को लागू करना है, लेकिन कुछ प्रकार के खेलों के लिए यह पर्याप्त होना चाहिए।

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


0

अपने विशेष मामले में प्रस्ताव को वापस करके रोलबैक को संभालना ठीक काम करना चाहिए। यदि आप AI इकाइयों के साथ किसी भी प्रकार के पाथफाइंडिंग का उपयोग कर रहे हैं, तो केवल ओवरलैपिंग इकाइयों से बचने के लिए रोलबैक के बाद इसे पुन: कनेक्ट करना सुनिश्चित करें।

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


0

जबकि यह एक दिलचस्प विचार है। मैं इसके खिलाफ सलाह दूंगा।

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

(1.1 + 3 - 3) == 1.1

C और C ++ में कम से कम, यह गलत है। जबकि अंतर छोटा हो सकता है, कल्पना करें कि 10 सेकंड के मिनट में 60fps पर कितनी त्रुटियां जमा हो सकती हैं। ऐसे मामले होंगे जहां एक खिलाड़ी केवल कुछ याद करता है, लेकिन खेल को पीछे की ओर दोहराए जाने पर इसे हिट करता है।

मैं हर आधे सेकंड में कीफोर स्टोर करने की सलाह दूंगा। यह बहुत अधिक मेमोरी नहीं लेगा। फिर आप या तो keyframes के बीच में अंतर कर सकते हैं, या इससे भी बेहतर, दो keyframes के बीच के समय का अनुकरण कर सकते हैं, और फिर इसे पीछे की ओर फिर से खेलना कर सकते हैं।

यदि आपका खेल बहुत जटिल नहीं है, तो खेल राज्य के 30 सेकंड के स्टोरफ्रेम को एक सेकंड में स्टोर करें और उस पीछे की तरफ खेलें। यदि आपके पास एक 2 डी स्थिति के साथ 15 ऑब्जेक्ट हैं, तो बिना संपीड़न के एक एमबी तक पहुंचने में अच्छा 1.5 मिनट लगेगा। कंप्यूटर में गीगाबाइट मेमोरी होती है।

इसलिए इसे ओवरकम्प्लीट न करें, किसी गेम को पीछे की ओर खेलना आसान नहीं होगा, और यह बहुत सारी त्रुटियों का कारण बनेगा।

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