গেম রাষ্ট্র পরিচালনার কৌশল?


24

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

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

আমি সীমাবদ্ধ রাষ্ট্রীয় মেশিন ব্যবহার করে এটি পরিচালনা করার অনেকগুলি সহজ উপায়ের কথা ভাবতে পারি, তবে আমি এগুলি দ্রুত হাত থেকে নামতেও দেখতে পারি। গেমের অবস্থা / স্থানান্তর সম্পর্কে নজর রাখার আরও মার্জিত উপায় থাকলে আমি কেবল কৌতূহলী।


আপনি কি গেমদেব.স্ট্যাকেক্সচেঞ্জ / সেকশনস / 1783 / game-state- stack এবং গেমদেব.স্ট্যাকেক্সেঞ্জের / জিজ্ঞাসা / 2423/ … পরীক্ষা করেছেন ? এটি একই ধরণের সমস্ত ধারণা একই ধীরে ধীরে ঝাঁপিয়ে পড়ে, তবে আমি গেম স্টেটের জন্য কোনও রাষ্ট্রের মেশিনের চেয়ে ভাল এমন কোনও বিষয় ভাবতে পারি না।
michael.bartnett

সম্ভাব্য অনুরূপ: gamedev.stackexchange.com/questions/12664/...
Tetrad

উত্তর:


18

আমি একবারে একটি নিবন্ধ জুড়ে এসেছি যা আপনার সমস্যাটি বেশ মার্জিতভাবে সমাধান করে। এটি একটি প্রাথমিক এফএসএম বাস্তবায়ন, এটি আপনার মূল লুপে ডাকা হয়। আমি এই উত্তরটির বাকি অংশে নিবন্ধটির মূল রুনডাউনটি রূপরেখা করেছি।

আপনার বেসিক গেমের অবস্থাটি দেখতে এমন দেখাচ্ছে:

class CGameState
{
    public:
        // Setup and destroy the state
        void Init();
        void Cleanup();

        // Used when temporarily transitioning to another state
        void Pause();
        void Resume();

        // The three important actions within a game loop
        void HandleEvents();
        void Update();
        void Draw();
};

প্রতিটি গেমের অবস্থা এই ইন্টারফেসের প্রয়োগ দ্বারা প্রতিনিধিত্ব করা হয়। আপনার ব্যাটলেস উদাহরণের জন্য, এর অর্থ এই রাজ্যগুলির অর্থ হতে পারে:

  • ভূমিকা অ্যানিমেশন
  • প্রধান সূচি
  • দাবা বোর্ড সেটআপ অ্যানিমেশন
  • প্লেয়ার মুভ ইনপুট
  • প্লেয়ার সরানো অ্যানিমেশন
  • প্রতিপক্ষ সরানো অ্যানিমেশন
  • বিরতি মেনু
  • endgame পর্দা

রাজ্যগুলি আপনার রাজ্যের ইঞ্জিনে পরিচালিত হয়:

class CGameEngine
{
    public:
        // Creating and destroying the state machine
        void Init();
        void Cleanup();

        // Transit between states
        void ChangeState(CGameState* state);
        void PushState(CGameState* state);
        void PopState();

        // The three important actions within a game loop
        // (these will be handled by the top state in the stack)
        void HandleEvents();
        void Update();
        void Draw();

        // ...
};

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

শেষ পর্যন্ত, আপনার প্রধান লুপটি কেবলমাত্র রাষ্ট্র ইঞ্জিনের সাথে ডিল করে:

int main ( int argc, char *argv[] )
{
    CGameEngine game;

    // initialize the engine
    game.Init( "Engine Test v1.0" );

    // load the intro
    game.ChangeState( CIntroState::Instance() );

    // main loop
    while ( game.Running() )
    {
        game.HandleEvents();
        game.Update();
        game.Draw();
    }

    // cleanup the engine
    game.Cleanup();
    return 0;
}

17
ক্লাসের জন্য সি? ইডব্ল্যু। তবে এটি একটি ভাল নিবন্ধ - +1 +
কমিউনিস্ট হাঁস

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

আমি মনে করি এটি কীভাবে কোড একসাথে মিলিত হয়েছে তার উপর নির্ভর করে। আমি কোনও টুকরা এবং গন্তব্য নির্বাচন করার (মূলত ইউআই সূচক এবং ইনপুট হ্যান্ডলিং) এবং দাবা টুকরোটির একটি অ্যানিমেশনটি সেই গন্তব্যের দিকে (পুরো বোর্ড অ্যানিমেশন যেখানে অন্যান্য টুকরা তাদের পথ থেকে সরে যায়, চলন্তর সাথে যোগাযোগ করে) এর মধ্যে পরিষ্কার বিচ্ছিন্নতা কল্পনা করতে পারি can টুকরো ইত্যাদি), রাজ্যগুলি অভিন্ন থেকে দূরে করে making এটি সহজেই রক্ষণাবেক্ষণ এবং পুনঃব্যবহারযোগ্যতা (ইন্ট্রো ডেমো, রিপ্লে মোড) এর অনুমতি প্রদান করে দায়িত্ব পৃথক করে। আমার মনে হয় এফএসএম ব্যবহার করে ঝামেলা হওয়ার দরকার নেই তা দেখানোর ক্ষেত্রে এটি প্রশ্নেরও উত্তর দেয়।
ভূত

এটি সত্যিই দুর্দান্ত, আপনাকে ধন্যবাদ। আপনার করা মূল বক্তব্যটি আপনার সর্বশেষ মন্তব্যে ছিল: "এফএসএম ব্যবহার করে ঝামেলা হওয়ার দরকার নেই।" আমি ভুল করে কল্পনা করেছিলাম যে এফএসএম ব্যবহারে সুইচ স্টেটমেন্ট ব্যবহার করা জড়িত, যা অগত্যা সত্য নয়। আর একটি মূল নিশ্চিতকরণ হ'ল প্রতিটি রাজ্যের গেম ইঞ্জিনের একটি রেফারেন্স প্রয়োজন; আমি ভাবলাম কীভাবে এটি কাজ করবে।
ভার্জিনিয়ান

2

এই ধরণের জিনিসটিকে সহজতম পদ্ধতিতে পরিচালনা করে আমি শুরু করি।

bool isPieceMoving;

তারপরে আমি সংশ্লিষ্ট জায়গাগুলিতে সেই বুলিয়ান পতাকার বিপরীতে চেকগুলি যুক্ত করব।

পরে যদি আমি দেখতে পাই যে এর চেয়ে আরও বেশি বিশেষ কেসগুলির দরকার - এবং কেবল এটি - আমি আরও ভাল কিছুতে পুনরায় ফ্যাক্টর করি। আমি গ্রহণ করব সাধারণত 3 টি পদ্ধতি আছে:

  • রিফ্যাক্টর কোনও এনামগুলিতে ফ্ল্যাগের প্রতিনিধিত্ব করে exclusive যেমন। enum { PRE_MOVE, MOVE, POST_MOVE }এবং যেখানেই প্রয়োজন স্থানান্তরগুলি যুক্ত করুন। তারপরে আমি এই এনামের বিরুদ্ধে পরীক্ষা করতে পারি যেখানে আমি বুলিয়ান পতাকার বিরুদ্ধে চেক করতাম। এটি একটি সাধারণ পরিবর্তন তবে যা আপনার বিরুদ্ধে পরীক্ষা করতে হবে তার সংখ্যা হ্রাস করে, কার্যকরভাবে আচরণ পরিচালনা করতে আপনাকে সুইচ স্টেটমেন্ট ব্যবহার করতে দেয় ইত্যাদি etc.
  • আপনার প্রয়োজন অনুসারে পৃথক সাবসিস্টেমগুলি স্যুইচ করুন। যুদ্ধের অনুক্রমের সময় যদি কেবলমাত্র পার্থক্যটি হয় আপনি টুকরো স্থানান্তর করতে পারবেন না, আপনি pieceSelectionManager->disable()ক্রমিকের শুরুতে কল করতে বা অনুরূপ করতে পারেন , এবং pieceSelectionManager->enable()। আপনার কাছে এখনও মূলত পতাকা রয়েছে, তবে এখন তারা নিয়ন্ত্রণ করা বস্তুর নিকটে সঞ্চিত রয়েছে এবং আপনার গেম কোডে আপনার কোনও অতিরিক্ত অবস্থা বজায় রাখতে হবে না।
  • পূর্ববর্তী অংশটি একটি পিসিলেকশন ম্যানেজারের অস্তিত্বকে বোঝায়: আরও সাধারণভাবে আপনি আপনার গেমের অবস্থা এবং আচরণের কিছু অংশকে ছোট ছোট বস্তুগুলিতে তৈরি করতে পারেন যা সামগ্রিক রাজ্যের একটি উপসেটকে সুসংগত উপায়ে পরিচালনা করে। এই বস্তুর প্রত্যেকটির নিজস্ব কিছু রাজ্য থাকবে যা এর আচরণটি নির্ধারণ করে তবে এটি অন্য বস্তু থেকে বিচ্ছিন্ন হওয়ার কারণে এটি পরিচালনা করা সহজ। আপনার গেমস্টেটের অবজেক্ট বা প্রধান লুপটি সিউডো-গ্লোবাল এবং ফ্যাক্টর যা সিফডো ফ্যাক্টরের জন্য একটি ডাম্পিং গ্রাউন্ডে পরিণত হতে দেয় তাড়িত হওয়ার প্রতিরোধ করুন!

সাধারণভাবে বলতে গেলে স্পেশাল-কেস সাবস্টেটগুলির ক্ষেত্রে আমার আর এর আগে আর কোনও দরকার হয় না, সুতরাং 'দ্রুত হাত থেকে বেরিয়ে যাওয়ার' এর ঝুঁকি আছে বলে আমি মনে করি না।


1
হ্যাঁ, আমি কল্পনা করেছি যে রাজ্যের সাথে সর্বাত্মকভাবে যাওয়া এবং যখন উপযুক্ত হবে তখন একটি বুল / এনাম ব্যবহারের মধ্যে একটি লাইন রয়েছে। তবে আমার পেডেন্টিক প্রবণতাগুলি জেনে আমি প্রায় প্রতিটি রাজ্যের নিজস্ব শ্রেণি তৈরি করতে চলেছি।
ভার্জিনিয়ান

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

1

http://www.ai-junkie.com/architecture/state_driven/tut_state1.html গেম স্টেট ম্যানেজমেন্টের জন্য একটি সুন্দর টিউটোরিয়াল! আপনি এটি গেম সত্তা বা উপরের মতো মেনু সিস্টেমের জন্য ব্যবহার করতে পারেন।

তিনি স্টেট ডিজাইন প্যাটার্ন সম্পর্কে শিক্ষাদান শুরু করেন এবং তারপরে একটি বাস্তবায়নে এগিয়ে চলেছেন State Machineএবং ক্রমাগত এটি আরও এবং আরও প্রসারিত করে। এটি খুব ভাল পড়া! কীভাবে পুরো ধারণাটি কাজ করে এবং কীভাবে এটি নতুন ধরণের সমস্যায় প্রয়োগ করা যায় তার একটি দৃ understanding় ধারণা দেবে!


1

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

আমি গেমপ্লেটি সাধারণত ক্রিয়া এবং ফলাফলের ক্রম হিসাবে ডিজাইন করি, যে কোনও গেমের অবস্থা আলাদাভাবে সংজ্ঞায়নের প্রয়োজন ছাড়াই স্বাভাবিকভাবে আসে।

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

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