আমি আমার তৈরি-সমস্ত-স্ট্যাটিক-এবং-গ্লোবাল ডিজাইনের ধরণটি থেকে মুক্তি পেতে চাই, তবে কীভাবে?


11

আমি মহাশূন্যে কিছুটা অন্ধকার ক্রোলার তৈরি করছি, এবং ইঞ্জিনের পিছনটি কীভাবে সুন্দর করা যায় সে সম্পর্কে আমি কিছু পরামর্শ শুনতে চাই। মূলত, বর্তমানে সমস্ত কিছু পরিচালকদের একটি ক্রপলোডের উপর ভিত্তি করে:

  • ব্যাকগ্রাউন্ড ম্যানেজার: AddBackground(image, parallax)শীতল পটভূমি প্রভাব তৈরি করার জন্য পদ্ধতি রয়েছে ।
  • কনফিগার ম্যানেজার: কনফিগার ফাইলটি পড়ে / তৈরি করে এবং সেই কনফিগারেশন ফাইল থেকে পড়া ডেটা ধারণ করে।
  • DrawManager: হয়েছে Draw(sprite)পর্দায় কাপড় আঁকা পদ্ধতি, এবং কিছু পছন্দ SetView(view), GetView()ইত্যাদি
  • সত্তা ম্যানেজার: সমস্ত সক্রিয় সত্তা ধারণ করে এবং সত্তা যুক্ত, অপসারণ এবং সন্ধানের জন্য পদ্ধতি রয়েছে।
  • DungeonManager (আসলে একটি GridManager বলা হয়, কিন্তু এই সরলতা জন্য): হয়েছে পদ্ধতি পছন্দ GenerateDungeon(), PlaceEnemies(), PlaceFinish()ইত্যাদি

এখন আমি আমার সমস্ত পরিচালকদের তালিকাভুক্ত এমনকি অর্ধেকও করছি না, তাই আমি মনে করি এটি পরিবর্তন হয়ে গেছে। আমার গেমটি স্ক্রিনগুলির উপর ভিত্তি করেও এটি আরও বিরক্তিকর করে তোলে কারণ আমার পরিচালকদের যে জিনিসগুলি পরিচালনা করছেন তার অর্ধেক অংশের দরকার নেই, উদাহরণস্বরূপ, প্রধান মেনু (আমার মূল মেনুতে আমার পদার্থবিজ্ঞান / সত্ত্বা / কোষাগার প্রয়োজন নেই) !)

এখন আমি ম্যানেজারকে অচল না করার বিষয়ে এবং আমার স্ক্রিনমেইনগেমকে সমস্ত গেম-সুনির্দিষ্ট পরিচালকদের একটি উদাহরণ দেওয়ার বিষয়ে ভেবেছিলাম। তবে এটি ম্যানেজারদের সাথে সম্পর্কিত যে কোনও কিছুকে কল / কল্পনা করে তোলে ... উদাহরণস্বরূপ, আমি যদি অন্ধকারের জায়গাটি এমন কোনও জায়গা থেকে আঁকতে চাইতাম তবে আমাকে এটি ScreenMainGame.Draw()করতে হবে ...

((ScreenMainGame)ScreenManager.CurrentScreen).GridManager.Draw()

এটা সত্যিই কুরুচিপূর্ণ।

সুতরাং, সহযোদ্ধা গেম ডেভেলপারগণ, এই গণ্ডগোলটি কীভাবে সমাধান করবেন সে সম্পর্কে আপনার কারও কি ধারণা আছে? আমি প্রশংসা করা হবে!


আপনাকে ঠিক কীভাবে সাহায্য করবেন তা সম্পর্কে আমি নিশ্চিত নই, তবে আমি নকশার নিদর্শনগুলির জন্য একটি ভাল বই পড়ার পরামর্শ দেব। আমি হেড ফার্স্ট ডিজাইনের প্যাটার্নগুলি পড়ছি এবং এটি বুঝতে খুব সহজ। উদাহরণগুলি জাভাতে রয়েছে তবে আমি মনে করি এটি আপনাকে সাহায্য করার জন্য সি # এর কাছাকাছি হবে। দুঃখিত, যদি আমার পরামর্শটি খুব নতুন হয়।
এম্প্লিফাইটি 91

গ্রাফিক্স কার্ডের সাথে ইন্টারফেস করতে আপনি কী ব্যবহার করছেন? XNA? SlimDX?
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

@ ব্লুরাজা: আমি এসএফএমএল.এনইটি ব্যবহার করছি।
Dlaor

সেক্ষেত্রে সি # তে এই সমস্যাগুলি মোকাবেলা করার জন্য আপনার সাধারণ পদ্ধতিগুলি ব্যবহার করা উচিত: নীচে আমার শেষ লিঙ্কটি দেখুন, পাশাপাশি নির্ভরতা ইনজেকশনটি কী?
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

উত্তর:


10

একটি উপাদান-ভিত্তিক ইঞ্জিন সম্পর্কে কী ?

আপনার নামের একটি প্রধান শ্রেণি থাকবে Engine, যা একটি তালিকা GameScreensরাখবে, যা তারা নিজেরাই একটি তালিকা রাখবে Components

ইঞ্জিনটির একটি Updateএবং একটি Drawপদ্ধতি রয়েছে এবং উভয়ই GameScreenএর পদ্ধতি Updateএবং Drawপদ্ধতিগুলিকে কল করে যা সেগুলি প্রতিটি উপাদানগুলির মাধ্যমে যায় এবং কল করে Updateএবং Draw

এর মতো উপস্থাপিত, আমি সম্মত হই যে এটি একটি দুর্বল এবং পুনরাবৃত্তি নকশার মতো শোনাচ্ছে। তবে বিশ্বাস করুন, আমার কোডটি আমার সমস্ত পুরানো পরিচালকের ক্লাসের চেয়ে কোনও উপাদান-ভিত্তিক পদ্ধতির ব্যবহার করে আরও ক্লিনার হয়ে উঠেছে ।

এ জাতীয় কোডটি বজায় রাখাও অনেক সহজ, যেহেতু আপনি কেবল একটি বড় শ্রেণির শ্রেণিবিন্যাসের মধ্য দিয়ে যাচ্ছেন এবং BackgroundManagerসমস্ত নির্দিষ্ট ভিন্ন ব্যাকগ্রাউন্ডের জন্য অনুসন্ধান করতে পারেন না । আপনি শুধুমাত্র একটি আছে ScrollingBackground, ParallaxBackground, StaticBackground, ইত্যাদি যা সব A থেকে আহরণ করা 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(উদাহরণস্বরূপ যখন ব্যবহারকারী স্টার্টগেম বোতামে ক্লিক করে আপনার মধ্যে স্থান MainMenuScreenপরিবর্তন করতে পারে GameplayScreen)।

Componentক্লাসের ক্ষেত্রেও এটি একই রকম হয় : এটিতে তার পিতামাতার রেফারেন্স রাখা উচিত GameScreen, Engineক্লাস এবং তার পিতামাতার উভয়ই GameScreenনতুন উপাদান যুক্ত করার অ্যাক্সেস থাকতে পারে (যেমন আপনি একটি এইচইউডি সম্পর্কিত ক্লাস তৈরি করতে পারেন DrawableButtonযা একটি DrawableTextউপাদান এবং একটি StaticBackgroundউপাদান রাখে ) holds

আপনি তার পরে অন্যান্য নকশার ধরণগুলিও প্রয়োগ করতে পারেন, যেমন "পরিষেবা নকশা প্যাটার্ন" (সঠিক নাম সম্পর্কে নিশ্চিত নয়) যেখানে আপনি নিজের Engineশ্রেণীর মধ্যে বিভিন্ন দরকারী পরিষেবাদি রাখতে পারবেন (আপনি কেবলমাত্র একটি তালিকা রাখবেন IServiceএবং অন্যান্য শ্রেণিগুলিকে পরিষেবাগুলি নিজেরাই যুক্ত করতে দিন )। উদাহরণস্বরূপ, Camera2Dঅন্যান্য উপাদানগুলি অঙ্কন করার সময় আমি রূপান্তরটি প্রয়োগ করার জন্য পরিষেবা হিসাবে আমার সমস্ত প্রকল্পের উপর একটি উপাদান রাখব। এটি এটিকে সর্বত্র প্যারামিটার হিসাবে পাস করা এড়িয়ে যায়।

উপসংহারে, অবশ্যই কোনও ইঞ্জিনের জন্য আরও ভাল ডিজাইন থাকতে পারে তবে আমি এই লিঙ্কটি দ্বারা প্রস্তাবিত ইঞ্জিনটি খুব মার্জিত, অত্যন্ত সহজেই রক্ষণযোগ্য এবং পুনরায় ব্যবহারযোগ্য হিসাবে দেখতে পেলাম । আমি ব্যক্তিগতভাবে কমপক্ষে এটি চেষ্টা করার পরামর্শ দেব।


1
এক্সএনএ, GameComponentএস এবং পরিষেবাদির মাধ্যমে এই বাহ্যিক-বাক্সকে সমর্থন করে । আলাদা Engineক্লাসের দরকার নেই ।
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

এই উত্তরের জন্য +1। এছাড়াও, গেম আপডেটের থ্রেড থেকে পৃথক থ্রেডে অঙ্কন করা কি অর্থপূর্ণ হবে?
f20k

1
@ ব্লুরাজা - ড্যানিপ্লুঘুফুট: আসলে তবে আমি ধরে নিয়েছিলাম এক্সএনএ ব্যবহার করা হয়নি তাই এটি কীভাবে করা যায় সে সম্পর্কে আমি আরও কিছুটা ব্যাখ্যা করেছি।
জেসি Emond

@ f20k: হ্যাঁ, এক্সএনএ এটি প্রায় একইভাবে করে। যদিও এটি বাস্তবায়িত হয় আমি জানি না। = / এটি কীভাবে করা যায় সে সম্পর্কে অবশ্যই ইন্টারনেটে কোথাও একটি নিবন্ধ থাকতে হবে। :)
জেসি Emond

হ্যাঁ, আমি এক্সএনএ ব্যবহার করছি না তবে এটি আমি যা করছি তার একটি দুর্দান্ত বিকল্প বলে মনে হচ্ছে। এর বাইরে আর কোনও বিকল্প আছে কিনা তা দেখার জন্য আমি বর্তমানে "হেড ফার্স্ট ডিজাইন প্যাটার্নস" বইটি পড়ছি। চিয়ার্স!
Dlaor

1

আপনি যা করতে চান তা হ'ল আপনার কোডটি উপাদান এবং পরিষেবাগুলিতে পৃথক করা। এক্সএনএ এর জন্য ইতিমধ্যে অন্তর্নির্মিত সমর্থন করেছে।

দেখুন এই নিবন্ধটি উপর GameComponentsএবং সেবা। তারপরে এক্সএনএ-তে পরিষেবাদি ব্যবহারের ক্ষেত্রে এই উত্তরটি দেখুন এবং কোনও ভাষায় পরিষেবাদির ক্ষেত্রে এটি আরও সাধারণ উত্তর


-3

এগুলি স্থির বা বৈশ্বিক হওয়ার অর্থ এই নয় যে তাদের সর্বদা লোড করা / আরম্ভ করতে হবে। একটি সিঙ্গলটন প্যাটার্ন ব্যবহার করুন এবং ম্যানেজারগুলিকে চাহিদা অনুযায়ী মুক্ত এবং লোড হওয়ার অনুমতি দিন।


4
ওপি এখানে সমাধানের চেষ্টা করছে এমন একটি অন্তর্নিহিত সমস্যাটির জন্য একটি সিঙ্গেলটন কেবল একটি মুখোমুখি।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.