XNA गेमकंप्यूटर (या किसी गेम में किसी भी प्रकार के घटकों के बीच) संचार की सुविधा के लिए मुझे किस तकनीक का उपयोग करना चाहिए?


9

मैं अपने पहले 'उचित' गेम प्रोजेक्ट पर शुरू कर रहा हूं, और मैंने अनिवार्य रूप से यह तय करने के लिए एक ब्लॉक मारा है कि XNA में गेम घटकों को कैसे संवाद करना चाहिए।

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

class SpriteManager
    Update(){
        if(player.collidesWith(enemy)
             // create new 'PlayerCollisionEvent'
    }

class HUDManager
    onPlayerCollisionEvent(){
        // Update the HUD (reduce lives etc)
    }

हालाँकि, मैं कोड सेटअप के बारे में निश्चित नहीं हूं (C # में) जो इसे पूरी तरह से पूरा करने के लिए आवश्यक होगा। क्या घटनाओं का ट्रैक रखता है (कुछ प्रकार की बस?), और यह कैसे संरचित है?

गेम सर्विसेज के बारे में भी बहुत कुछ बताया गया है, जिसके द्वारा आप अपने मुख्य Game.cs वर्ग में एक गेमकॉमॉप्टेंट को पंजीकृत कर सकते हैं, फिर इसे अपने कोड में कहीं से भी लाएं जिसमें मुख्य 'गेम' ऑब्जेक्ट का संदर्भ हो। मैंने अपने स्प्राइटबच ऑब्जेक्ट के साथ यह कोशिश की है और यह बहुत आसान लगता है .. हालांकि, मैं इसे इवेंट मॉडल के रूप में लचीला नहीं देख सकता।

उदाहरण के लिए ले लो जब एक दुश्मन मर जाता है। हम गेम स्कोर को अपडेट करना चाहते हैं। सेवाओं का उपयोग करके मैं गेम 1 में बनाई गई मेरी StateManager ऑब्जेक्ट का संदर्भ प्राप्त कर सकता हूं और एक सेवा के रूप में जोड़ा जा सकता हूं, फिर नए मूल्य पर 'स्कोर' सेट कर सकता हूं। मैंने सोचा था कि एक 'onEnemyDeath' घटना, जिसे कई वर्गों की भीड़ द्वारा अलग-अलग तरीके से नियंत्रित किया जा सकता है, लेकिन संबंधित 'दुश्मन की मौत का पता लगाने' अनुभाग में कोड की 1 पंक्ति द्वारा शुरू किया गया, व्यक्तिगत रूप से प्रत्येक आवश्यक GameComentent को कास्टिंग करने से बेहतर होगा जो फिर कॉल करना तरीकों की आवश्यकता है।

या ये हीन रणनीति कुछ और है?

मुझे लगता है कि यह आंशिक रूप से मेरे गरीब सी # ज्ञान के रूप में खेल संचार प्रतिमानों के रूप में ज्यादा है, लेकिन मैं वास्तव में इस मूलभूत चीज को प्राप्त करना चाहूंगा।

अपडेट करें

सेवाओं पर नज़र रखने के बारे में अधिक विस्तार से मैं कम आश्वस्त हूं - यह मूल रूप से एक वैश्विक चर के आसपास से गुजर रहा है (जो मुझे समझ में आता है)।

अपडेट २

इवेंट हैंडलिंग और नमूना कोड के परीक्षण पर इस मूल ट्यूटोरियल पर एक नज़र रखने के बाद लगता है कि मैं जो चर्चा कर रहा हूं, उसके लिए एक तार्किक विकल्प होगा। लेकिन मैंने जो सैंपल देखे हैं, उसमें इसका ज्यादा इस्तेमाल नहीं कर सकता। क्या कोई स्पष्ट कारण है कि किसी को क्यों नहीं करना चाहिए?


मेरा सुझाव है कि आप पहले FlatRedBall आज़माएँ। यह XNA के शीर्ष पर बैठता है और जीवन को वास्तव में आसान बनाता है।
ashes999

3
मैं वास्तव में एक इंजन में कूदने से पहले क्या चल रहा है की मूल बातें समझना चाहूंगा।
कोडिंगहैंड्स

मुझे लगता है कि यहां आपकी असफलता वास्तव में C # के बारे में जानकारी की कमी है। सी # आमतौर पर कक्षाओं के बीच संचार की सुविधा के लिए घटनाओं का उपयोग करता है। यह वास्तव में आप पर निर्भर है कि इसे कैसे किया जाए - XNA एक स्प्राइटबैच क्लास प्रदान करता है, और अधिकांश कार्य आपको लिखना है। एक इंजन आपको एक ठोस विचार देगा कि विवरण में गोता लगाने से पहले चीजें उच्च स्तर पर कैसे काम करती हैं।
ashes999

1
मैं एक हद तक सहमत हूं, लेकिन जब से मैंने गेमकॉर्पोरेटर्स के बीच अधिकांश इंटरक्लास संचार पढ़ा है, सेवाओं का उपयोग करके किया जा सकता है। मुझे घटनाओं का उपयोग करने की आदत है। मुझे यकीन नहीं है कि जो सबसे अच्छा है, या यदि वैध विकल्प (एकल, स्थिर वर्ग हैं जो
ग्लोबल्स के

जवाबों:


4

पिछले (जावा) जीयूआई प्रोग्रामिंग घटनाओं से, हैंडलर और श्रोता आगे बढ़ने के तरीके की तरह लग रहे थे। इसलिए मेरे पास किसी प्रकार की ईवेंट बस होगी, जो उन ईवेंट्स के लिए ईवेंट पंजीकरण और कक्षाओं को स्वीकार करती है, जिनसे निपटने के लिए हैंडलर हैं।

C # में इवेंट बसों के बारे में आपको बहुत कुछ नहीं मिलेगा, क्योंकि मुझे नहीं लगता कि जावा के बाहर कोई भी इस तरह की 'कॉल' को अपने अनुभव में बताता है। अधिक सामान्य शब्द संदेश कतार, इवेंट मैनेजर, सिग्नल / स्लॉट, प्रकाशित / सदस्यता, आदि हो सकते हैं।

काम करने वाले खेल बनाने के लिए आपको उनमें से किसी की आवश्यकता नहीं है, लेकिन अगर आप इस तरह की प्रणाली के साथ सहज हैं, तो यह आपको यहां भी अच्छी तरह से काम करेगा। दुर्भाग्य से कोई भी आपको वास्तव में एक बनाने के लिए नहीं बता सकता है क्योंकि हर कोई उन्हें थोड़ा अलग तरीके से रोल करता है, अगर वे उन्हें बिल्कुल भी उपयोग करते हैं। (मैं उदाहरण के लिए नहीं है।) आप System.Collections.Generic.List<Event>कतार के लिए एक सरल के साथ शुरू कर सकते हैं , आपके विभिन्न कार्यक्रम इवेंट के उपवर्ग और प्रत्येक ईवेंट प्रकार के लिए ग्राहकों की एक सूची के साथ। कतार में प्रत्येक घटना के लिए, ग्राहकों की सूची प्राप्त करें, और प्रत्येक ग्राहक के लिए, handle(this_event)उस पर कॉल करें । फिर इसे कतार से हटा दें। दोहराएँ।

गेम सर्विसेज के बारे में भी बहुत कुछ बताया गया है, जिसके द्वारा आप अपने मुख्य Game.cs वर्ग में एक गेमकॉमॉप्टेंट को पंजीकृत कर सकते हैं, फिर इसे अपने कोड में कहीं से भी लाएं जिसमें मुख्य 'गेम' ऑब्जेक्ट का संदर्भ हो। मैंने अपने स्प्राइटबच ऑब्जेक्ट के साथ यह कोशिश की है और यह बहुत आसान लगता है .. हालांकि, मैं इसे इवेंट मॉडल के रूप में लचीला नहीं देख सकता।

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

मुझे लगता है कि यह आंशिक रूप से मेरे गरीब सी # ज्ञान के रूप में खेल संचार प्रतिमानों के रूप में ज्यादा है, लेकिन मैं वास्तव में इस मूलभूत चीज को प्राप्त करना चाहूंगा।

C # जावा के लिए एक समान भाषा है। आपने जावा में जो कुछ भी किया वह C # में किया जा सकता है, बस अलग-अलग सिंटैक्स के साथ। यदि आपको किसी अवधारणा का अनुवाद करने में परेशानी होती है, तो यह शायद इसलिए है क्योंकि आप केवल इसके लिए एक जावा-विशिष्ट नाम जानते हैं।


साभार @Kylotan जिज्ञासा से बाहर, आप खुद को अंतर-संचार संचार के लिए किस प्रणाली का उपयोग करते हैं - सेवाएं दृष्टिकोण या कुछ और?
कोडिंगहैंड्स

AFAIK, इवेंट बसें संदेश पंक्तिबद्ध सामग्री के समान हैं, लेकिन घटनाओं के लिए।
ashes999

2
@ कोडिंगहैंड्स, मैं आमतौर पर किसी भी औपचारिक इंटरक्लास संचार विधि का उपयोग नहीं करता हूं। मैं बस चीजों को सरल रखता हूं - यदि एक वर्ग को दूसरे को कॉल करने की आवश्यकता होती है, तो आमतौर पर या तो पहले से ही सदस्य के रूप में दूसरी कक्षा का संदर्भ होता है, या दूसरे वर्ग को एक तर्क के रूप में पारित किया जाता है। कभी-कभी हालांकि जब मैं यूनिटी इंजन के साथ काम कर रहा होता हूं, तो उसके पास एक दृष्टिकोण होता है, जिसे आप 'सेवाओं' का दृष्टिकोण कह रहे होते हैं, तो मैं उस नाम से एक ऑब्जेक्ट को देखूंगा जिसके पास मेरे लिए आवश्यक घटक है, घटक को देखें ऑब्जेक्ट पर, फिर उस घटक पर विधियों को कॉल करें।
काइलोटन

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

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

1

क्या आपने केवल साधारण स्थिर घटनाओं का उपयोग करने की कोशिश की है? उदाहरण के लिए, यदि आप चाहते थे कि आपका स्कोर वर्ग इस बारे में जाने कि दुश्मन की मृत्यु कब हुई, तो आप ऐसा कुछ करेंगे:

Score.cs

class Score
{
    public int PlayerScore { get; set; }

    public Score()
    {
        EnemySpaceship.Death += new EventHandler<SpaceshipDeathEventArgs>(Spaceship_Death);
    }

    private void Spaceship_Death(object sender, SpaceshipDeathEventArgs e)
    {
        PlayerScore += e.Points;
    }
}

EnemySpaceship.cs

class EnemySpaceship
{
    public static event EventHandler<SpaceshipDeathEventArgs> Death;

    public void Kill()
    {
        OnDeath();
    }

    protected virtual void OnDeath()
    {
        if (Death != null)
        {
            Death(this, new SpaceshipDeathEventArgs(50));
        }
    }
}

SpaceshipDeathEventArgs.cs

class SpaceshipDeathEventArgs : EventArgs
{
    public int Points { get; private set; }

    internal SpaceshipDeathEventArgs(int points)
    {
        Points = points;
    }
}

1

यदि आप ईवेंट-आधारित दृष्टिकोण से असहज महसूस करते हैं, तो आर्टेमिस सी # आज़माएं, यह एक एंटिटी सिस्टम फ्रेमवर्क पर आधारित है http://t-machine.org/index.php/2007/09/03/entity-systems.are -इस-भविष्य के- MMOG-विकास-भाग -1 /

स्रोत: https://github.com/tilianuxlich/artemis_CSharp उदाहरण खेल: https://github.com/tilinuxlich/starwarrior_CSharp


0

इवेंट एग्रीगेटर को इस तरह उपयोग करने का प्रयास करें


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