2009-04-28 4 views
11

मैं जावा में एक ग्रिड आधारित गेम बना रहा हूं और मैं गेम रिकॉर्डिंग और प्लेबैक को कार्यान्वित करना चाहता हूं। मुझे यकीन नहीं है कि यह कैसे करें, हालांकि मैंने 2 विचारों पर विचार किया है:गेम प्लेबैक को लागू करने का सबसे अच्छा तरीका?

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

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

गेम प्लेबैक को लागू करने का सबसे अच्छा तरीका क्या है?

संपादित करें- मुझे यकीन नहीं है कि मेरा गेम कितना निर्धारक है, इसलिए मुझे यकीन नहीं है कि पूरे गेम को केवल कुंजीस्ट्रोक और माउस क्लिक रिकॉर्ड करके एक साथ पाई जा सकती है।

उत्तर

14

एक अच्छी प्लेबैक तंत्र ऐसा कुछ नहीं है जिसे बिना किसी भिन्न भिन्नता के गेम में जोड़ा जा सके। सबसे अच्छा यह होगा कि गेम इंफ्रास्ट्रक्चर को इसके साथ दिमाग में डिजाइन किया जाए। इस तरह के एक खेल बुनियादी ढांचे को प्राप्त करने के लिए command pattern का उपयोग किया जा सकता है।

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

public interface Command{ 
    void execute(); 
} 
public class MoveRightCommand implements Command { 
    private Grid theGrid; 
    private Player thePlayer; 

    public MoveRightCommand(Player player, Grid grid){ 
     this.theGrid = grid; 
     this.thePlayer = player; 
     } 

    public void execute(){ 
    player.modifyPosition(0, 1, 0, 0); 
    } 
} 

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

+2

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

+0

यह पैटर्न आपको पूर्ववत/फिर से क्षमता भी दे सकता है। –

2

क्यों कई बार एक दूसरे रिकॉर्ड नहीं और फिर अपने उत्पादन सेक, या शायद ऐसा करते हैं:

recordInitialState(); 
... 
runs 30 times a second: 
recordChangeInState(previousState, currentState); 
... 

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

3

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

मेरी चिंता यह है कि यदि आपके पास ऐसी कोई तंत्र नहीं है जो समान समय पर घटनाओं को संदर्भित कर सके, तो आपके कोड वितरित उपयोगकर्ताओं को प्रबंधित करने के तरीके में कोई समस्या हो सकती है।

उदाहरण के लिए एक्सबॉक्स 360 पर हेलो 3 जैसे गेम पर विचार करें - प्रत्येक क्लाइंट सर्वर-आधारित सुधार सहित गेम के बारे में उनके विचार को रिकॉर्ड करता है।

2

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

2

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

लेकिन, ऐसा लगता है कि उपयोगकर्ता के इनपुट को केवल सहेजने के लिए सबसे अच्छा तरीका हो सकता है, जैसा कि बताया गया था, और या तो गेम में सभी कलाकारों/sprites की स्थिति को एक ही समय में स्टोर करना, जो कि सरल है जैसे ही दिशा, वेग और टाइल एक्स, वाई, या, यदि सबकुछ निर्धारित हो सकता है तो अभिनेताओं/sprites को अनदेखा करें क्योंकि आप उनकी जानकारी प्राप्त कर सकते हैं।

बेहतर गेम देने के लिए आपका गेम गैर-निर्धारक भी उपयोगी होगा।

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

8

शॉन हरग्रेव्स ने अपने ब्लॉग पर हाल ही में एक पोस्ट पोस्ट किया था कि उन्होंने मोटोजीपी में रीप्ले को कैसे लागू किया। कई अलग-अलग दृष्टिकोण और उनके पेशेवरों और विपक्षों पर जाता है।

http://blogs.msdn.com/shawnhar/archive/2009/03/20/motogp-replays.aspx

2

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

दिलचस्प बात यह है कि यह नेटवर्किंग के साथ आपको मिली समस्या के समान ही है। एक कंप्यूटर कैसे सुनिश्चित करता है कि किसी अन्य कंप्यूटर को गेम स्टेटस से अवगत कराया जाता है, बिना किसी अव्यवस्थित उच्च आवृत्ति पर उस पूरे गेम स्टेट को भेजने के बिना? सामान्य दृष्टिकोण घटना अधिसूचनाओं और राज्य अपडेट के बेस्पेक मिश्रण होने के समाप्त होता है, जो शायद आपको यहां की आवश्यकता होगी।

1

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

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