घटक-आधारित इंजन के बारे में क्या ?
आपके पास एक मुख्य वर्ग Engine
होगा, जो एक सूची रखेगा GameScreens
, जो स्वयं की एक सूची रखेगा Components
।
इंजन एक है Update
और एक Draw
तरीका है और दोनों कॉल GameScreen
की Update
और Draw
विधियों, जो खुद को हर घटक और कॉल के माध्यम से जाना Update
और Draw
।
इस तरह प्रस्तुत, मैं सहमत हूं कि यह एक खराब और दोहरावदार डिजाइन की तरह लगता है। लेकिन मेरा विश्वास करो, मेरे सभी पुराने प्रबंधक वर्गों के साथ घटक-आधारित दृष्टिकोण का उपयोग करके मेरा कोड बहुत अधिक साफ हो गया ।
इस तरह के कोड को बनाए रखना बहुत सरल है, क्योंकि आप सिर्फ एक बड़े वर्ग के पदानुक्रम से गुजर रहे हैं और BackgroundManager
सभी विशिष्ट विभिन्न पृष्ठभूमि के लिए खोज नहीं कर रहे हैं । तुम सिर्फ एक है ScrollingBackground
, ParallaxBackground
, StaticBackground
, आदि जो सभी एक से निकाले जाते हैं Background
वर्ग।
आप अंततः एक बहुत ही ठोस इंजन का निर्माण करेंगे, जिसका उपयोग आप अपनी सभी परियोजनाओं पर बहुत अधिक उपयोग किए जाने वाले घटकों और सहायक तरीकों के साथ कर सकते हैं (जैसे FrameRateDisplayer
कि डिबगिंग उपयोगिता के रूप में, एक Sprite
वर्ग के रूप में एक बुनियादी स्प्राइट और वैक्टर के लिए विस्तार विधियों के साथ। (यादृच्छिक संख्या पीढ़ी)।
अब आपके पास एक BackgroundManager
वर्ग नहीं होगा , लेकिन एक Background
वर्ग जो इसके बजाय खुद का प्रबंधन करेगा।
जब आपका खेल शुरू होता है, तो आपको बस यही करना होता है:
// when declaring variables:
Engine engine;
// when initializing:
engine = new Engine();
engine.Initialize();
engine.LoadContent();
engine.AddGameScreen(new MainMenuScreen());
// when updating:
engine.Update();
// when drawing:
engine.Draw();
और यह आपके गेम स्टार्ट कोड के लिए है।
फिर, मुख्य मेनू स्क्रीन के लिए:
class MainMenuScreen : MenuScreen // where MenuScreen derives from the GameScreen class
{
const int ENEMY_COUNT = 10;
StaticBackground background;
Player player;
List<Enemy> enemies;
public override void Initialize()
{
background = new StaticBackground();
player = new Player();
enemies = new List<Enemy>();
base.AddComponent(background); // defined within the GameScreen class
base.AddComponent(player);
for (int i = 0; i < ENEMY_COUNT; ++i)
{
Enemy newEnemy = new Enemy();
enemies.Add(newEnemy);
base.AddComponent(newEnemy);
}
}
}
आप सामान्य विचार प्राप्त करें।
आप Engine
अपनी सभी GameScreen
कक्षाओं के भीतर का संदर्भ भी रखेंगे , ताकि एक GameScreen
वर्ग के भीतर भी नई स्क्रीन को जोड़ सकें (जैसे कि जब उपयोगकर्ता आपके भीतर StartGame बटन पर क्लिक करता है MainMenuScreen
, तो आप संक्रमण कर सकते हैं GameplayScreen
)।
वही Component
कक्षा के लिए जाता है : उसे अपने माता-पिता के संदर्भ को धारण करना चाहिए GameScreen
, नए घटकों को जोड़ने के लिए Engine
कक्षा और उसके अभिभावक दोनों के पास होना चाहिए GameScreen
(जैसे कि आप एक HUD से संबंधित वर्ग बना सकते हैं जिसे DrawableButton
एक
DrawableText
घटक और एक StaticBackground
घटक कहते हैं)।
आप इसके बाद अन्य डिज़ाइन पैटर्न भी लागू कर सकते हैं, जैसे "सर्विस डिज़ाइन पैटर्न" (सटीक नाम के बारे में निश्चित नहीं) जहां आप अपनी Engine
कक्षा के भीतर विभिन्न उपयोगी सेवाएं रख सकते हैं (आप बस अपनी सूची बनाकर रख सकते हैं IService
और अन्य कक्षाओं को स्वयं सेवाओं को जोड़ने दें )। उदाहरण के लिए, मैं Camera2D
अपने सभी प्रोजेक्ट पर एक घटक को एक सेवा के रूप में रखूंगा जब अन्य घटकों को आरेखित करने के लिए इसके परिवर्तन को लागू किया जा सके। यह हर जगह इसे एक पैरामीटर के रूप में पारित करने से बचा जाता है।
निष्कर्ष में, निश्चित रूप से एक इंजन के लिए अन्य बेहतर डिजाइन हो सकते हैं, लेकिन मैंने इस लिंक द्वारा प्रस्तावित इंजन को बहुत सुरुचिपूर्ण, बेहद आसानी से बनाए रखने योग्य और पुन: प्रयोज्य पाया। मैं व्यक्तिगत रूप से इसे कम से कम आजमाने की सलाह दूंगा।