বড় গেমগুলিতে ইনপুট পরিচালনার কৌশল


16

বড় গেমগুলিতে ইনপুট পরিচালনা করার জন্য কি কোনও মানক কৌশল রয়েছে। বর্তমানে, আমার প্রকল্পে, সমস্ত ইনপুট হ্যান্ডলিং গেম লুপে সম্পন্ন হয়, যেমন:

while(SDL_PollEvent(&event)){
            switch(event.type){
                case SDL_QUIT:
                    exit = 1;
                    break;
                case SDL_KEYDOWN:
                    switch(event.key.keysym.sym){
                        case SDLK_c:
                            //do stuff
                            break;
                    }
                    break;
                case SDL_MOUSEBUTTONDOWN:
                    switch(event.button.button){
                        case SDL_BUTTON_MIDDLE:
                                //do stuff
                                break;
                            }
                    }
                    break;
            }

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


ইভেন্ট ম্যানেজারের সাহায্যে আপনি ইভেন্টটিকে ইনপুটগুলিতে ফায়ার করতে পারেন এবং আপনার গেমের অন্যান্য সমস্ত অংশগুলিতে তাদের নিবন্ধ করতে দেয়।
দানিজার

@ ডানিজার আপনাকে ইভেন্ট ম্যানেজার বলতে আসলে কী বোঝাতে চাইছে, আপনি কী ধরণের কথা বলছেন তা দেখানোর জন্য যদি আপনি কিছু কঙ্কালের সিউডো কোড সরবরাহ করতে পারেন তবে এটি কি সম্ভব?
w4etwetewtwet


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

উত্তর:


12

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

ইভেন্ট ম্যানেজার হ'ল একটি গ্লোবাল ক্লাস যা উভয়কেই কীগুলিতে কলব্যাক ফাংশনগুলি রেজিস্টার করতে এবং সেই কলব্যাকগুলি বন্ধ করতে দেয়। ইভেন্ট ম্যানেজার তাদের কী দ্বারা গোষ্ঠীভুক্ত একটি ব্যক্তিগত তালিকায় নিবন্ধিত ফাংশন সংরক্ষণ করে। প্রতিবার কোনও কী বরখাস্ত হওয়ার সাথে সাথে সমস্ত নিবন্ধিত কলব্যাকগুলি কার্যকর করা হয়।

কলব্যাকগুলি এমন std::functionবস্তু হতে পারে যা ল্যাম্বডাস ধারণ করতে পারে। কীগুলি স্ট্রিং হতে পারে। যেহেতু পরিচালকটি বিশ্বব্যাপী, আপনার আবেদনের উপাদানগুলি অন্যান্য উপাদান থেকে বরখাস্ত কীগুলিতে নিবন্ধভুক্ত করতে পারে।

// in character controller
// at initialization time
Events->Register("Jump", [=]{
    // perform the movement
});

// in input controller
// inside the game loop
// note that I took the code structure from the question
case SDL_KEYDOWN:
    switch(event.key.keysym.sym) {
    case SDLK_c:
        Events->Fire("Jump");
        break;
    }
    break;

অতিরিক্ত যুক্তি হিসাবে মানগুলি পাস করার জন্য আপনি এমনকি এই ইভেন্টটির পরিচালককে প্রসারিত করতে পারেন। সি ++ টেমপ্লেটগুলি এটির জন্য দুর্দান্ত। আপনি যেমনটি বলার জন্য এই জাতীয় সিস্টেমটি ব্যবহার করতে পারেন, কোনও "WindowResize"ইভেন্টের জন্য নতুন উইন্ডো আকারটি পাস করুন, যাতে শোনার উপাদানগুলি এগুলি নিজেরাই আনতে না পারে। এটি কোড নির্ভরতা কিছুটা হ্রাস করতে পারে।

Events->Register<int>("LevelUp", [=](int NewLevel){ ... });

আমি আমার গেমের জন্য এই জাতীয় ইভেন্টের ব্যবস্থা গ্রহণ করেছি। আপনি যদি আগ্রহী হন তবে আমি কোডটির লিঙ্কটি এখানে পোস্ট করব।

ইভেন্ট ম্যানেজার ব্যবহার করে, আপনি সহজেই আপনার অ্যাপ্লিকেশনটির মধ্যে ইনপুট তথ্য সম্প্রচার করতে পারেন। তদ্ব্যতীত, এটি ব্যবহারকারীর কী বাইন্ডিংগুলি কাস্টমাইজ করতে দেয় এমন এক দুর্দান্ত উপায়ের অনুমতি দেয়। উপাদানগুলি সরাসরি কীগুলির "PlayerJump"পরিবর্তে ( পরিবর্তে "KeyPressedSpace") শব্দার্থক ইভেন্টগুলি শোনায় । তারপরে আপনার কাছে একটি ইনপুট ম্যাপিং উপাদান থাকতে "KeyPressedSpace"পারে যা ব্যবহারকারী সেই কীটির সাথে আবদ্ধ হওয়া যেকোন ক্রিয়া শোনেন এবং ট্রিগার করে।


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

আমি কেবল কিছু ভেবেছি, আমি কি এই জাতীয় কোনও ফাংশন পাস করতে পারি, বা রেজিস্টার ফাংশনটিতে AClass :: func নিতে হবে না, এটি একটি শ্রেণীর সদস্যের ফাংশনে সীমাবদ্ধ
w4etwetewtwet

এটি সি ++ এ ল্যাম্বডা এক্সপ্রেশন সম্পর্কে দুর্দান্ত জিনিস, আপনি একটি ক্যাপচার ক্লজ নির্দিষ্ট করতে পারেন [=]এবং ল্যাম্বদা থেকে অ্যাক্সেস করা সমস্ত স্থানীয় ভেরিয়েবলের উল্লেখগুলি অনুলিপি করা হবে। সুতরাং আপনি এই পয়েন্টার বা এই জাতীয় কিছু পাস করতে হবে না। তবে মনে রাখবেন যে আপনি পুরানো সি ফাংশন পয়েন্টারে ক্যাপচার ক্লজ সহ ল্যাম্বডাস সংরক্ষণ করতে পারবেন না । তবে সি ++ ঠিকঠাক std::functionকাজ করে।
দানিজার

std :: ফাংশনটি খুব ধীর
থেস্টেটেজেজ

22

এটি কয়েকটি স্তরগুলিতে বিভক্ত করুন।

নিম্নতম স্তরে আপনার ওএস থেকে কাঁচা ইনপুট ইভেন্ট রয়েছে। এসডিএল কীবোর্ড ইনপুট, মাউস ইনপুট, জৌস্টিক ইনপুট ইত্যাদি You

এগুলি আপনি খুব নিম্ন-স্তরের কাস্টম ইভেন্ট ধরণের, যেমন "কীবোর্ড বোতাম ডাউন" বা এর মতো দিয়ে বিমূর্ত করতে পারেন। যখন আপনার প্ল্যাটফর্ম স্তর (এসডিএল গেম লুপ) ইনপুট গ্রহণ করে, তখন এই নিম্ন-স্তরের ইভেন্টগুলি তৈরি করা উচিত এবং তারপরে এগুলি একটি ইনপুট পরিচালককে ফরোয়ার্ড করা উচিত। এটি সাধারণ পদ্ধতির কল, কলব্যাক ফাংশন, একটি জটিল ইভেন্ট সিস্টেমের সাহায্যে এটি করতে পারে যা আপনার ভাল লাগে।

ইনপুট সিস্টেমটির এখন নিম্ন-স্তরের ইনপুটটিকে উচ্চ-স্তরের যৌক্তিক ইভেন্টগুলিতে অনুবাদ করার কাজ রয়েছে। গেম যুক্তি মোটেই যত্ন করে না যে স্পেস চাপছে। এটি যত্নশীল যে JUMP টিপেছিল। ইনপুট পরিচালকের কাজ হ'ল এই নিম্ন-স্তরের ইনপুট ইভেন্টগুলি সংগ্রহ করা এবং উচ্চ-স্তরের ইনপুট ইভেন্টগুলি তৈরি করা। এটি জেনে যাওয়ার জন্য দায়ী যে স্পেসবার এবং 'এ' গেমপ্যাড বোতামটি উভয়ই লজিকাল কমান্ড জাম্পের মানচিত্র। এটি গেমপ্যাড বনাম মাউস লুক নিয়ন্ত্রণ এবং আরও অনেক কিছু নিয়ে কাজ করে। এটি উচ্চ-স্তরের যৌক্তিক ইভেন্টগুলি নির্গত করে যা নিম্ন-স্তরের নিয়ন্ত্রণগুলি থেকে যতটা সম্ভব বিমূর্ত (এখানে কিছু সীমাবদ্ধতা রয়েছে তবে সাধারণ ক্ষেত্রে আপনি জিনিসগুলি সম্পূর্ণ বিমূর্ত করতে পারেন)।

আপনার অক্ষর নিয়ামক এরপরে এই ইভেন্টগুলি গ্রহণ করে এবং প্রকৃত প্রতিক্রিয়া জানাতে এই উচ্চ-স্তরের ইনপুট ইভেন্টগুলি প্রক্রিয়া করে। প্ল্যাটফর্ম স্তরটি ইভেন্টটি "কী ডাউন স্পেসবারে" পাঠিয়েছে। ইনপুট সিস্টেমটি এটি পেয়েছিল, এর ম্যাপিং সারণী / যুক্তি দেখায় এবং তারপরে ইভেন্টটি "চাপানো জাম্প" প্রেরণ করে। গেম লজিক / চরিত্র নিয়ামক সেই ইভেন্টটি গ্রহণ করে, খেলোয়াড়কে আসলে লাফ দেওয়ার অনুমতি দেয় কিনা তা পরীক্ষা করে এবং তারপরে "প্লেয়ার লাফানো" ইভেন্টটি প্রকাশ করে (বা কেবল সরাসরি লাফিয়ে উঠার কারণ ঘটায়), যা বাকি গেম যুক্তি যা কিছু করতে ব্যবহার করে ।

গেম লজিকের উপর নির্ভর করে যে কোনও কিছু প্লেয়ার নিয়ামকের মধ্যে যায়। ওএস নির্ভর যেকোন কিছু প্ল্যাটফর্ম স্তরটিতে যায়। বাকিগুলি ইনপুট ম্যানেজমেন্ট স্তরে যায়।

এটি বর্ণনা করতে এখানে কিছু অপেশাদার এএসসিআইআই শিল্প রয়েছে:

-----------------------------------------------------------------------
Platform Abstraction | Collect and forward OS input events
-----------------------------------------------------------------------
                          | |
                          | |
                         \   /
                          \_/
-----------------------------------------------------------------------
    Input Manager    | Translate OS input events into logical events
-----------------------------------------------------------------------
                          | |
                          | |
                         \   /
                          \_/
-----------------------------------------------------------------------
Character Controller | React to logical events and affect game play
-----------------------------------------------------------------------
                          | |
                          | |
                         \   /
                          \_/
-----------------------------------------------------------------------
      Game Logic     | React to player actions and provides feedback
-----------------------------------------------------------------------

দুর্দান্ত ASCII শিল্প, তবে এটি প্রয়োজনীয় নয়, আমি দুঃখিত। আমি পরিবর্তে একটি সংখ্যাযুক্ত তালিকা ব্যবহার করার পরামর্শ দিচ্ছি। যাইহোক একটি ভাল উত্তর!
দানিজার

1
@ দানিজার: এহ, আমি পরীক্ষা করছিলাম, এর আগে কখনও উত্তর আঁকার চেষ্টা করিনি। এটির চেয়ে মূল্য বেশি কাজ, তবে পেইন্ট প্রোগ্রামের সাথে কাজ করার চেয়ে অনেক কম কাজ। :)
শান মিডলডিচ

ঠিক আছে, বোধগম্য :-)
ডানিজার

8
ব্যক্তিগতভাবে, আমি বোসিং সংখ্যাযুক্ত তালিকার চেয়ে ASCII শিল্পের চেয়ে বেশি পছন্দ করি।
জেসি এমন্ড 21

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