गेम्स में ड्राइंग और लॉजिक का अलग होना


11

मैं एक डेवलपर हूं जो अभी खेल विकास के साथ खिलवाड़ करना शुरू कर रहा हूं। मैं .Net लड़का हूँ, इसलिए मैंने XNA के साथ खिलवाड़ किया है और अब iPhone के लिए Cocos2d के साथ खेल रहा हूँ। मेरा प्रश्न वास्तव में अधिक सामान्य है।

मान लीजिए कि मैं एक साधारण पोंग गेम बना रहा हूं। मैं एक Ballवर्ग और एक Paddleवर्ग होता। व्यवसाय की दुनिया के विकास से आ रहा है, मेरी पहली वृत्ति इन वर्गों में से किसी में भी ड्राइंग या इनपुट हैंडलिंग कोड नहीं है।

//pseudo code
class Ball
{
   Vector2D position;
   Vector2D velocity;
   Color color;
   void Move(){}
}

बॉल क्लास में कुछ भी इनपुट को हैंडल नहीं करता है, या ड्राइंग से संबंधित नहीं है। मैं तब एक और वर्ग, मेरी Gameकक्षा, या मेरी Scene.m(Cocos2d में) करूँगा जो बॉल को नया करेगा और गेम लूप के दौरान, यह आवश्यकतानुसार गेंद को हेरफेर करेगा।

हालाँकि, XNA और Cocos2d दोनों के लिए कई ट्यूटोरियल में, मुझे इस तरह एक पैटर्न दिखाई देता है:

//pseudo code
class Ball : SomeUpdatableComponent
{
   Vector2D position;
   Vector2D velocity;
   Color color;
   void Update(){}
   void Draw(){}
   void HandleInput(){}
}

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


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

@tenpn, आपकी टिप्पणी से लगता है कि आपको नहीं लगता कि यह अच्छा अभ्यास है, मुझे आश्चर्य हुआ कि क्या आप आगे बता सकते हैं? मैंने हमेशा सोचा था कि यह उन विधियों के कारण सबसे उपयुक्त व्यवस्था थी, जो प्रत्येक प्रकार के लिए बहुत विशिष्ट है; लेकिन मुझे अपने आप को बहुत कम अनुभव है इसलिए मुझे आपके विचार सुनने में दिलचस्पी होगी।
सीबीएफ

1
@ यदि आप डेटा-ओरिएंटेड डिज़ाइन में हैं तो यह काम नहीं करता है, और यदि आप ऑब्जेक्ट-ओरिएंटेड डिज़ाइन पसंद करते हैं तो यह काम नहीं करता है। अंकल बॉब के ठोस प्रिंट
tenpn

@tenpn। उस लेख और दस्तावेज़ के भीतर जुड़े बहुत दिलचस्प हैं, धन्यवाद!
sebf

जवाबों:


10

मेरा सवाल है, क्या यह सही है? क्या यह वह पैटर्न है जिसका उपयोग लोग खेल विकास में करते हैं?

गेम डेवलपर जो भी काम करते हैं उसका उपयोग करते हैं। यह कठोर नहीं है, लेकिन हे, यह जहाजों।

यह किसी भी तरह से मेरी बॉल क्लास को सब कुछ करने के लिए मेरे द्वारा उपयोग की जाने वाली हर चीज के खिलाफ जाता है।

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

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

जिम्मेदारी का प्रतिनिधिमंडल प्रोग्रामर तक है; एक साधारण पोंग गेम के लिए, यह समझ में आता है कि प्रत्येक ऑब्जेक्ट अपनी ड्राइंग (निम्न-स्तरीय कॉल के साथ) पूरी तरह से संभालता है। यह शैली और ज्ञान की बात है।

इसके अलावा, इस दूसरे उदाहरण में, जहां मेरी बॉल को पता है कि कैसे घूमना है, मैं पैडल से टकराव का पता कैसे लगाऊंगा? क्या गेंद को पैडल का ज्ञान होना चाहिए?

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

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

फिर, आपको बस एक समझ विकसित करनी होगी (या अपना दिमाग बनाना होगा) कि आपके खेल में अलग-अलग चीजों के लिए जिम्मेदारी कैसे सौंपी जानी चाहिए। प्रतिपादन एक एकान्त गतिविधि है और एक निर्वात में किसी वस्तु द्वारा नियंत्रित किया जा सकता है; टक्कर और भौतिकी आम तौर पर नहीं हो सकती।

मेरे पहले उदाहरण में, गेम क्लास में बॉल और पैडल दोनों का संदर्भ होगा, और फिर उन दोनों को कुछ CollisionDetection मैनेजर या कुछ और के लिए भेज दिया जाएगा, लेकिन मैं विभिन्न घटकों की जटिलता से कैसे निपटूं, यदि प्रत्येक व्यक्तिगत घटक करता है सब कुछ खुद?

इसके अन्वेषण के लिए ऊपर देखें। यदि आप एक ऐसी भाषा में हैं जो आसानी से इंटरफेस का समर्थन करती है (यानी, जावा, सी #), तो यह आसान है। यदि आप C ++ में हैं, तो यह दिलचस्प हो सकता है। मैं इन मुद्दों को हल करने के लिए मैसेजिंग का उपयोग करने का पक्ष लेता हूं (कक्षाएं उन संदेशों को संभाल सकती हैं, जो दूसरों को अनदेखा कर सकते हैं), घटक रचना जैसे कुछ अन्य लोग।

फिर, जो भी काम करता है और आपके लिए सबसे आसान है।


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

5

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

आपको इसे पढ़ना चाहिए:

http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/

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

मेरी पुनरावृत्तियों इस प्रकार है:

पहले पुनरावृत्ति में एक "एंटिटी सिस्टम" ऑब्जेक्ट था जो एडम के रूप में वर्णित था; हालाँकि मेरे घटकों में अभी भी विधियाँ थीं- मेरे 'रेंडर करने योग्य' घटक में एक पेंट () विधि थी, और मेरी स्थिति घटक में एक चाल () विधि और आदि थे जब मैंने उन संस्थाओं को बाहर करना शुरू कर दिया जिन्हें मैंने महसूस किया कि मुझे बीच संदेश भेजने की आवश्यकता है। घटकों और घटकों अद्यतन के निष्पादन का आदेश .... जिस तरह से बहुत गड़बड़ है।

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

वैसे भी यात्रा # 2 के लिए यह वही है जो मैंने ब्लॉग से प्राप्त किया था:

EntityManager - घटक "डेटाबेस" के रूप में कार्य करता है, जो कि उन संस्थाओं के लिए क्वियर किया जा सकता है जिनमें कुछ प्रकार के घटक होते हैं। यह भी शीघ्र पहुँच के लिए इन-मेमोरी डेटाबेस द्वारा समर्थित हो सकता है ... अधिक जानकारी के लिए टी-मशीन पार्ट 5 देखें।

EntitySystem - प्रत्येक प्रणाली अनिवार्य रूप से केवल एक विधि है जो एंटाइट्स के सेट पर संचालित होती है। प्रत्येक सिस्टम एक एक्स या वाई के घटक x का उपयोग करेगा ताकि वह काम कर सके। तो आप घटक x, y और z के साथ संस्थाओं के लिए प्रबंधक को क्वेरी करेंगे और फिर उस परिणाम को सिस्टम में पास करेंगे।

इकाई - सिर्फ एक आईडी, एक लंबे समय की तरह। इकाई वह है जो समूहों के एक समूह को एक 'इकाई' में एक साथ सम्मिलित करती है।

घटक - खेतों का एक सेट .... कोई व्यवहार नहीं! जब आप व्यवहार जोड़ना शुरू करते हैं तो यह गड़बड़ हो जाता है ... यहां तक ​​कि एक साधारण अंतरिक्ष आक्रमणकारियों के खेल में भी।

संपादित करें : वैसे, 'dt' अंतिम मुख्य लूप आह्वान के बाद का डेल्टा समय है

तो मेरा मुख्य आक्रमणकारी पाश यह है:

Collection<Entity> entitiesWithGuns = manager.getEntitiesWith(Gun.class);
Collection<Entity> entitiesWithDamagable =
manager.getEntitiesWith(BulletDamagable.class);
Collection<Entity> entitiesWithInvadorDamagable = manager.getEntitiesWith(InvadorDamagable.class);

keyboardShipControllerSystem.update(entitiesWithGuns, dt);
touchInputSystem.update(entitiesWithGuns, dt);
Collection<Entity> entitiesWithInvadorMovement = manager.getEntitiesWith(InvadorMovement.class);
invadorMovementSystem.update(entitiesWithInvadorMovement);

Collection<Entity> entitiesWithVelocity = manager.getEntitiesWith(Velocity.class);
movementSystem.move(entitiesWithVelocity, dt);
gunSystem.update(entitiesWithGuns, System.currentTimeMillis());
Collection<Entity> entitiesWithPositionAndForm = manager.getEntitiesWith(Position.class, Form.class);
collisionSystem.checkCollisions(entitiesWithPositionAndForm);

यह पहली बार में थोड़ा अजीब लगता है, लेकिन यह अविश्वसनीय रूप से लचीला है। इसे अनुकूलित करना भी बहुत आसान है; विभिन्न घटक प्रकारों के लिए आपके पास पुनर्प्राप्ति को तेज़ बनाने के लिए अलग-अलग बैकिंग डेटस्टोर्स हो सकते हैं। A फॉर्म ’वर्ग के लिए आप टक्कर का पता लगाने के लिए गति बढ़ाने के लिए इसे क्वाडट्री के साथ रख सकते हैं।

मैं आप की तरह हूँ; मैं एक अनुभवी डेवलपर हूं, लेकिन गेम लिखने का कोई अनुभव नहीं था। मैंने कुछ समय शोध करके देव पैटर्न दिया, और इसने मेरी आंख को पकड़ लिया। यह किसी भी तरह से चीजों को करने का एकमात्र तरीका नहीं है, लेकिन मैंने इसे बहुत सहज और मजबूत पाया है। मेरा मानना ​​है कि श्रृंखला "गेम प्रोग्रामिंग जेम्स" की पुस्तक 6 में पैटर्न पर आधिकारिक रूप से चर्चा की गई थी - http://www.amazon.com/Game-Programming-Gems/dp/1584500492 । मैंने स्वयं कोई पुस्तक नहीं पढ़ी है लेकिन मुझे लगता है कि वे गेम प्रोग्रामिंग के लिए वास्तविक संदर्भ हैं।


1

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

अब, मेरी व्यक्तिगत पसंद पर, मैं न्यूनतम वस्तुओं के होते हुए, व्यवहार द्वारा कोड को अलग करना चाहता हूं (एक वर्ग / आकर्षित करने के लिए, दूसरे को अद्यतन करने के लिए)। मुझे समानांतर करना आसान लगता है, और मैं अक्सर अपने आप को एक ही समय में कम फ़ाइलों पर काम कर पाता हूं। मैं कहूंगा कि यह चीजों को करने का एक प्रक्रियात्मक तरीका है।

लेकिन अगर आप व्यवसाय की दुनिया से आते हैं, तो आप शायद लिखने की कक्षाओं के आसपास अधिक सहज हैं जो जानते हैं कि अपने लिए सब कुछ कैसे करना है।

एक बार फिर, मैं आपको लिखने की सलाह देता हूं जो आपको लगता है कि आपके लिए सबसे स्वाभाविक है।


मुझे लगता है कि आपने मेरे सवाल को गलत समझा। मैं कह रहा हूं कि मुझे ऐसी कक्षाएं पसंद नहीं हैं जो सब कुछ खुद करते हैं। मैं एक गेंद की तरह गिर गया, बस एक गेंद का एक तार्किक प्रतिनिधित्व होना चाहिए, हालांकि यह गेम लूप, इनपुट हैंडलिंग आदि के बारे में कुछ भी नहीं पता होना चाहिए ...
BFree

व्यापार प्रोग्रामिंग में निष्पक्ष होने के लिए, यदि आप इसे उबालते हैं, तो दो ट्रेनें हैं: व्यापारिक वस्तुएं जो खुद पर तर्क लोड करती हैं, जारी रखती हैं और प्रदर्शन करती हैं, और DTO + AppLogic + Repository / Persitance Layer ...
Nate

1

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

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

ज्यादातर लोग एक इनपुट क्लास का उपयोग करते हैं जिसके परिणाम या तो सर्विस या स्टेटिक क्लास के माध्यम से सभी गेम ऑब्जेक्ट्स के लिए उपलब्ध होते हैं।


0

मुझे लगता है कि आप व्यवसाय की दुनिया में जो भी उपयोग कर रहे हैं वह अमूर्त और कार्यान्वयन को अलग कर रहा है।

खेल देव दुनिया में, आप आमतौर पर गति के संदर्भ में सोचना चाहते हैं। आपके पास अधिक संदर्भ स्विच होने वाली अधिक वस्तुएं होंगी जो वर्तमान लोड के आधार पर चीजों को धीमा कर सकती हैं।

यह केवल मेरी अटकलें हैं क्योंकि मैं एक वानाबे गेम डेवलपर हूं लेकिन एक प्रोफेसनल डेवलपर।


0

नहीं, यह 'सही' या 'गलत' नहीं है, यह सिर्फ एक सरलीकरण है।

कुछ व्यवसाय कोड बिल्कुल समान हैं, जब तक कि आप एक ऐसी प्रणाली के साथ काम नहीं कर रहे हैं जो प्रस्तुति और तर्क को जबरन अलग करती है।

यहां, एक VB.NET उदाहरण, जहां "बिजनेस लॉजिक" (एक नंबर को जोड़ना) एक GUI इवेंट हैंडलर में लिखा गया है - http://www.homeandlearn.co.uk/net/nets1p12.html

मैं विभिन्न घटकों की जटिलता से कैसे निपटूं, यदि प्रत्येक व्यक्तिगत घटक स्वयं सब कुछ करता है?

यदि और जब यह उस जटिल हो जाता है, तो आप इसे बाहर कर सकते हैं।

class Ball
{
    GraphicalModel ballVisual;
    void Draw()
    {
        ballVisual.Draw();
    }
};

0

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

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