अद्यतन (पुनर्कथन)
जब से मैंने एक बल्कि मौखिक उत्तर लिखा है, यहाँ यह सब उबलता है:
- नाम स्थान अच्छे हैं, जब भी यह समझ में आता है, उनका उपयोग करें
- उपयोग
inGameIO
और playerIO
कक्षाओं में संभवतः एसआरपी का उल्लंघन होगा। इसका मतलब है कि आप आवेदन तर्क के साथ IO को संभालने के तरीके को युग्मित कर रहे हैं।
- सामान्य IO वर्गों की एक जोड़ी है, जो हैंडलर कक्षाओं द्वारा उपयोग की जाती हैं (या कभी-कभी साझा की जाती हैं)। ये हैंडलर क्लासेस तब कच्चे इनपुट का एक प्रारूप में अनुवाद करेंगे, जिस पर आपका एप्लिकेशन लॉजिक समझ सकता है।
- एक ही आउटपुट के लिए जाता है: यह काफी सामान्य कक्षाओं द्वारा किया जा सकता है, लेकिन गेम स्टेट को एक हैंडलर / मैपर ऑब्जेक्ट के माध्यम से पास करें जो आंतरिक गेम स्टेट को जेनेरिक IO कक्षाओं को संभाल सकता है।
मुझे लगता है कि आप इसे गलत तरीके से देख रहे हैं। आप अनुप्रयोग के घटकों के कार्य में IO को अलग कर रहे हैं, जबकि - मेरे लिए- यह स्रोत के आधार पर अलग IO वर्ग और IO के "प्रकार" के लिए अधिक समझ में आता है ।
कुछ बेस / जेनेरिक KeyboardIO
क्लासेस के MouseIO
साथ शुरू करने के लिए, और उसके बाद आपको कब और कहाँ उनकी ज़रूरत है, इसके आधार पर, उपवर्ग होते हैं जो हैंडल को IO को अलग तरीके से कहते हैं।
उदाहरण के लिए, टेक्स्ट इनपुट एक ऐसी चीज है जिसे आप शायद अलग-अलग इन-गेम नियंत्रणों को संभालना चाहते हैं। आप प्रत्येक उपयोग के मामले के आधार पर खुद को कुछ खास तरह की नक्शों को देखना चाहते हैं, लेकिन यह मैपिंग आईओ का हिस्सा नहीं है, यह है कि आप आईओ को कैसे संभाल रहे हैं।
एसआरपी से चिपके हुए, मेरे पास कुछ कक्षाएं होंगी जो मैं कीबोर्ड आईओ के लिए उपयोग कर सकता हूं। स्थिति के आधार पर, मैं शायद इन वर्गों के साथ अलग तरीके से बातचीत करना चाहता हूं, लेकिन उनका एकमात्र काम मुझे यह बताना है कि उपयोगकर्ता क्या कर रहा है।
फिर मैं इन ऑब्जेक्ट्स को एक हैंडलर ऑब्जेक्ट में इंजेक्ट करूँगा जो या तो कच्चे IO को किसी चीज़ पर मैप करेगा, जो कि मेरे एप्लिकेशन लॉजिक के साथ काम कर सकता है (जैसे: यूजर प्रेस "w" , हैंडलर मैप्स उस पर MOVE_FORWARD
)।
ये हैंडलर, बारी-बारी से पात्रों को स्थानांतरित करने के लिए उपयोग किए जाते हैं, और तदनुसार स्क्रीन को आकर्षित करते हैं। एक सकल निरीक्षण, लेकिन इसका सार इस तरह की संरचना है:
[ IO.Keyboard.InGame ] // generic, if SoC and SRP are strongly adhered to, changing this component should be fairly easy to do
||
==> [ Controls.Keyboard.InGameMapper ]
[ Game.Engine ] <- Controls.Keyboard.InGameMapper
<- IO.Screen
<- ... all sorts of stuff here
InGameMapper.move() //returns MOVE_FORWARD or something
||
==> 1. Game.updateStuff();//do all the things you need to do to move the character in the given direction
2. Game.Screen.SetState(GameState); //translate the game state (inverse handler)
3. IO.Screen.draw();//generate actual output
अब हमारे पास एक ऐसा वर्ग है जो अपने कच्चे रूप में कीबोर्ड IO के लिए जिम्मेदार है। एक अन्य वर्ग जो इस डेटा को गेम इंजन में बदल देता है, वास्तव में इसका अर्थ समझ सकता है, इस डेटा का उपयोग तब शामिल सभी घटकों की स्थिति को अपडेट करने के लिए किया जाता है, और अंत में, एक अलग वर्ग स्क्रीन पर आउटपुट का ख्याल रखेगा।
हर एक वर्ग के पास एक ही काम होता है: कीबोर्ड इनपुट को संभालना एक ऐसे वर्ग द्वारा किया जाता है, जो यह नहीं जानता / परवाह करता है / यह जानना चाहता है कि यह इनपुट का क्या मतलब है। यह सब पता है कि इनपुट कैसे प्राप्त करें (बफर, असंबद्ध, ...)।
हैंडलर इस जानकारी का अर्थ बनाने के लिए आवेदन के बाकी हिस्सों के लिए एक आंतरिक प्रतिनिधित्व में अनुवाद करता है।
खेल इंजन उस डेटा को लेता है जिसका अनुवाद किया गया था, और इसका उपयोग सभी प्रासंगिक घटकों को सूचित करने के लिए करता है कि कुछ चल रहा है। इन घटकों में से प्रत्येक बस एक काम करते हैं, चाहे वह टकराव की जाँच हो, या चरित्र एनीमेशन में परिवर्तन हो, इससे कोई फर्क नहीं पड़ता, यह प्रत्येक व्यक्तिगत वस्तु के लिए नीचे है।
ये ऑब्जेक्ट्स अपने राज्य को वापस रिले करते हैं, और यह डेटा पास हो जाता है Game.Screen
, जो कि एक उलटा आईओ हैंडलर है। यह आंतरिक IO.Screen
आउटपुट को वास्तविक आउटपुट उत्पन्न करने के लिए उपयोग कर सकते हैं।