আমি কীভাবে ক্লাসের মধ্যে ডেটা এবং নির্ভরতা পরিষ্কারভাবে এবং মার্জিতভাবে পরিচালনা করতে পারি


12

আমি এসএফএমএল 2 তে 2 ডি টপডাউন গেমটিতে কাজ করছি এবং একটি দুর্দান্ত উপায় খুঁজে বের করতে হবে যাতে সমস্ত কিছু একসাথে কাজ করবে এবং ফিট করবে।

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

গেম লুপে, আমি আপডেটটি কল করি এবং তারপরে প্রতিটি ক্লাসে আঁকি, আমি কল্পনা করি এটি একটি দুর্দান্ত সাধারণ পদ্ধতি। আমার কাছে টাইলস, সংঘর্ষ, প্লেয়ার এবং একটি রিসোর্স ম্যানেজারের ক্লাস রয়েছে যাতে সমস্ত টাইলস / চিত্র / টেক্সচার রয়েছে। এসএফএমএলে যেভাবে ইনপুট কাজ করে তার কারণে আমি সিদ্ধান্ত নিয়েছি যে প্রতিটি ক্লাসের হ্যান্ডেল ইনপুট (যদি প্রয়োজন হয়) তার আপডেট কলে হবে।

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

এটি বেশিরভাগ অংশের জন্য দুর্দান্ত কাজ করে তবে আমি বিশ্বাস করি এটি আরও ভালভাবে করা যায়, কীভাবে আমি ঠিক তা নিশ্চিত নই।

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

  • প্লেয়ারটি কীপ্রেসে কোনও লুটযোগ্য আইটেমের সীমাতে রয়েছে কিনা তা পরীক্ষা করুন, না হলে এগিয়ে যান না।
  • আইটেমটি সন্ধান করুন।
  • আইটেমের স্প্রাইট টেক্সচারটি তার ডিফল্ট টেক্সচার থেকে একটি "লুটেড" জমিনে আপডেট করুন।
  • আইটেমটির জন্য সংঘর্ষ আপডেট করুন: এটি আকার পরিবর্তন করেছে বা পুরোপুরি সরানো হয়েছে।
  • যোগ করা আইটেমটি সহ জায় আপডেট করা দরকার।

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

কোন সহায়তা / পরামর্শ প্রশংসা করা হবে! যদি কিছু অস্পষ্ট হয় তবে আমি জিনিসগুলিতে প্রসারিত হয়ে খুশি।


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

5
রচনা সম্পর্কিত ক্যানন নিবন্ধগুলির মধ্যে একটি: আপনার
শ্রেণিবিন্যাসকে বিকশিত করুন

খুব স্থানীয় বলে মনে হচ্ছে। কোড পর্যালোচনা এসই চেষ্টা করে দেখুন?
আনকো

উত্তর:


5

রচনাগুলি সমস্ত সমস্যার সমাধান করবে কিনা তা নিশ্চিত নয়। আংশিক সাহায্য করতে পারে। আপনি যদি চান তবে ক্লাসগুলি ডিকুয়াল করা আমি আরও ঘটনা চালিত যুক্তি সন্ধান করব। এই উপায় যেমন আপনার অনলুট ফাংশন থাকবে যার নিকটতম সন্ধানের জন্য প্লেয়ারের অবস্থান এবং লুটগুলি সম্পর্কিত তথ্য থাকতে হবে। তারপরে ফাংশন লুট হওয়া আইটেমটিতে ইভেন্ট প্রেরণ করে। এর ইভেন্ট প্রক্রিয়া চক্রের লুট আইটেমগুলি এই ইভেন্টটি পরিচালনা করে তাই আইটেমটি কেবল কীভাবে নিজেকে আপডেট করতে হয় তা জানতে হবে। অনলুট ফাংশন প্লেয়ারের তালিকা আপডেট করতে পারে বা আইটেম নিজেই আপডেট পাঠাতে পারে ইনভেন্টরি / * অনলুটসুসেস * ইভেন্ট এবং প্লেয়ার / ইনভেন্টরি এটিকে নিজের প্রক্রিয়া ইভেন্ট পরিচালনা করবে।

পেশাদাররা: আপনি আপনার কয়েকটি ক্লাস ডিক্লুপ করেছেন

কনস: যুক্ত ইভেন্ট ক্লাস, সম্ভবত অপরিবর্তিত কোড ওভারহেড

এটি দেখতে কেমন হতে পারে তার এক সম্ভাব্য উপায়:

case LOOT_KEY:
   OnLoot(PLayer->getPos(), &inventoryItems);
....

// note onLoot do not needs to know anything about InvItem class (forward decl in enough)
int onLoot(vec3 pos, InvItems& pitems)
{
    InvItem* pitem = findInRange(pos, pitems, LOOT_RANGE);
    if(pitem)
     EventManager::Instance->post( Event::makeLootEvent(pitem));
}
....

// knows only about EventManager
InvItem::processEvents()
{
    while(!events.empty())
    {
        Event* pev = events.pop();
        ...
        case LOOT_EVENT:
            // in case you broadcasted it, but better is to sort all posted/sent events and add them only if they addressed to particular item 
            if(pev->item == this && handleLoot((LootEvent)pev))
            {
                EventManager::Instance->post(Event::makeLootSuccessEvent(this));
            }
    }
}

int handleLoot(LootEvent* plootev)
{
    InvItem* pi = plootev->item;
    if(pi->canLoot())
    {
        updateTexture(pi->icon, LOOTED_ICON_RES);
        return true;
    }
    return false; 
}


...
// knows only LootSuccessEvent and player
Inventory::processEvents()
{
    while(!events.empty())
    {
        Event* pev = events.pop();
        ...
        case LOOT_SUCCESS_EVENT:
             player->GetInventory()->add( ((LootSuccessEvent*)pev)->item );
        ...
}

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

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