আমার গেম লুপ থেকে কোনও সত্তা মারা যাওয়ার পরে আমি কীভাবে সরিয়ে ফেলব?


16

ঠিক আছে তাই আমার কাছে আমার সমস্ত সত্ত্বার একটি বড় তালিকা রয়েছে যা আমি লুপ করে আপডেট করি। এএস 3-তে আমি এটি অ্যারে (গতিশীল দৈর্ঘ্য, টাইপযুক্ত), ভেক্টর (টাইপড) বা একটি লিঙ্কযুক্ত তালিকার (নেটিভ নয়) হিসাবে সঞ্চয় করতে পারি। এই মুহুর্তে আমি অ্যারে ব্যবহার করছি তবে আমি দ্রুততর হলে ভেক্টর বা লিঙ্কযুক্ত তালিকায় পরিবর্তনের পরিকল্পনা করছি।

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


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

উত্তর:


13

আমি সমস্ত অ্যাড / রিমুভগুলি পৃথক তালিকায় সংরক্ষণ করব এবং আপডেট-লুপের মাধ্যমে পুনরাবৃত্তি করার পরে operations ক্রিয়াকলাপগুলি করব।


10

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


1
ফ্লিক্সেলের জন্য +1। deadসত্যিকার অর্থে পুনর্ব্যবহার করা পারফরম্যান্সে সহায়তা করে।
তুষার অন্ধ

3

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

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

void updateGame()
{
  // updateEntities()
  Entity* pSrcEntity = &mEntities[0];
  Entity* pDstEntity = &mEntities[0];
  newNumEntities = 0;
  for (int i = 0; i < numEntities; i++)
  {
    if (!pSrcEntity->isDead)
    {
       // could be inline but whatever.
       updateEntity(pDstEntity, pSrcEntity);
       // if entity just died, don't update the pDstEntity pointer, 
       // and just let the next entity updated overwrite it.
       if (!pDstEntity->isDead)
       {
          pDstEntity++;
          newNumEntities++;
       }
    }
    pSrcEntity++;
  }
}
numEntities = newNumEntities;

এই এই প্রকল্পের বৈশিষ্ট্যগুলি:

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

+1 টি। আমি এই পছন্দ। যদিও আমি কখনও একটি পুলের মধ্যে অর্ডার আপডেটের প্রয়োজন হয় না তা আমি মনে করি এটির জিনিসগুলির ব্যাগে আমি যুক্ত করব যদি মনে হয় যে আমি পরিস্থিতিটি চালিয়ে যাচ্ছি: ও)
কাজ

2

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

আমরা আসলে প্রকৃতপক্ষে চ্যাটরুমে রিসোর্স পুলিংয়ের কথা বলছিলাম। এটি একটি খুব ভাল অনুশীলন, এবং আপনি এটি করছেন তা শুনে ভাল লাগবে। :)


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

বাহ, খুব ভাল পয়েন্ট কাজ! :)
রিকিট

2

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

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

আমি বহু প্রকল্পে বহুভুজ-ডেটাস্ট্রাকচার ব্যবহার করেছি এবং তাদের সাথে খুব খুশি হয়েছি।

সম্পাদনা: দুঃখিত, আমি মনে করি উত্তর অপসারণের কৌশলটির দিক থেকে খুব স্পষ্ট ছিল না: আমি তালিকাটি আইটেমটি মারা যাওয়ার সাথে সাথে সরিয়ে ফেলতে এবং সরাসরি পুলিং-কাঠামোয় (পুনর্ব্যবহারযোগ্য) যুক্ত করার পরামর্শ দিই । যেহেতু একটি লিঙ্কযুক্ত তালিকা থেকে কোনও আইটেম সরিয়ে ফেলা খুব পারফরম্যান্ট, তাই আমি এটি করতে সমস্যা দেখছি না।


1
আমি ধরে নিলাম যে আপনি এখানে একটি ডাবল-লিঙ্কযুক্ত তালিকার পরামর্শ দিচ্ছেন? (এগিয়ে / ফিরে)? এছাড়াও: আপনি কি লিঙ্ক-উপাদানগুলির উপর কোনও ধরণের পুলের পরামর্শ দিচ্ছেন বা আপনি সংযুক্ত তালিকার প্রতিটি পয়েন্টার-ধারককে গতিশীলভাবে বরাদ্দ দিচ্ছেন?
সাইমন

হ্যাঁ, এটি একটি ডাবল-লিঙ্কযুক্ত-তালিকা হতে হবে যা সেই কাজের জন্য সবচেয়ে উপযুক্ত। যে ইশারা জন্য ধন্যবাদ! আইটেমগুলির পুনরায় ব্যবহার সম্পর্কে: আমি একটি বিশেষায়িত পুলিং ক্লাস / ডেটাস্ট্রাকচারের কথা ভাবছিলাম, যা এমন একটি নতুন চাহিদা তৈরি করে বা পুলের মধ্যে কিছু থাকলে বিদ্যমান উদাহরণগুলি ব্যবহার করে। সুতরাং তালিকা থেকে "মৃত" আইটেমগুলি সরিয়ে ফেলা এবং পরে ব্যবহারের জন্য সেগুলিতে যুক্ত করা ভাল হবে।
বাম্মজ্যাক

একক লিঙ্কযুক্ত তালিকা জরিমানা করবে। দ্বিগুণভাবে লিঙ্কযুক্ত তালিকাগুলি কেবল উভয় দিকেই পুনরাবৃত্তি করার সুবিধা দেয়। বর্তমান আইটেমটি সরিয়ে ফেলার বিকল্প সহ একক সংযুক্ত তালিকার মাধ্যমে পুনরাবৃত্তি করতে আপনাকে পূর্বের এন্ট্রিটির উপর নজর রাখতে হবে।
deft_code

@ ক্যাসপিন হ্যাঁ ঠিক আপনি যদি একটি একক-লিঙ্কযুক্ত-তালিকা ব্যবহার করছেন, তবে আপনাকে পূর্ববর্তী নোডগুলি ট্র্যাক করে রাখতে হবে এবং nextমুছার পরে নোডের সাথে তাদের পয়েন্টারটি লিঙ্ক করতে হবে। আপনি যদি নিজে নিজে এটি করার ঝামেলা না চান, তবে একটি ডাবল-লিঙ্কযুক্ত-তালিকাটি হবে পছন্দের ডেটা স্ট্রাকচার।
বাম্মজ্যাক

1

"আমাকে এড়িয়ে চলুন, আমি মরে গেছি" বলার জন্য এটির জন্য কেবল একটি পতাকা লাগান I'm "আমি আমার সত্ত্বাগুলি বানাচ্ছি, সুতরাং মৃত একটি সত্তা আবার কোনও সময় বেঁচে থাকার সম্ভাবনা রয়েছে" say

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


0

আমি ব্যবহৃত একটি স্বচ্ছন্দে পাওয়া একটি পরিষ্কার এবং সাধারণ সমাধান হ'ল লকযোগ্য মানচিত্রটি ব্যবহার করা।

আপনার 2 টি অপারেশন রয়েছে lock()এবং unlock()আপনি যখন মানচিত্রটি পুনরাবৃত্তি করবেন তখন আপনি পাবেনlock() এখনই এই বিন্দু থেকে মানচিত্রের প্রতিটি ক্রিয়াকলাপ কার্যকর করে না, এটি কেবল CommandQueueএকবার কল করার পরে চালানো হবে unlock()

সুতরাং কোনও সত্তা অপসারণ করার জন্য নিম্নলিখিত সিউডো কোড থাকবে:

void lockableMap::remove(std::string id) {
   if(isLocked) {
       commandQueue.add(new RemoveCommand(id));
   } else {
       //remove element from map
   }

এবং যখন আপনি unlock()

isLocked = false
commandQueue.execute(this);

আপনাকে কেবলমাত্র বিবেচনা করতে হবে তা হ'ল আপনি কেবল লুপের পরে সত্তাটি সরিয়ে ফেলবেন।

সম্পাদনা: এটি সাইমন প্রস্তাবিত সমাধান।



0

আমার দুটি পদ্ধতি আছে।

আপনি যখন কোনও বস্তুকে মুছে ফেলার জন্য কল করবেন তখন এটি দুটি পতাকা সেট করে:

1. ধারকটি বলতে যে কোনও জিনিস মুছে ফেলা হয়েছে

২. কনটেইনারটি জানাতে কোন বিষয়গুলি মুছতে অনুরোধ করা হয়েছে

void object::deleteObject()
{
    container->objectHasBeenDeleted = true;
    isToDelete = true;
}

এক অবজেক্টের ভেক্টর ব্যবহার করে

std::vector<object*> objects;

তারপরে আপডেট ফাংশনে, কোনও বস্তু মুছে ফেলা হয়েছে কিনা তা পরীক্ষা করে দেখুন এবং যদি সমস্ত বস্তুর মধ্যে পুনরাবৃত্তি হয় এবং মুছার পতাকা রয়েছে এমনগুলি সরিয়ে ফেলুন

void container::update()
{
    if (objectHasBeenDeleted)
    {
        std::vector<object*>::iterator ListIterator;
        for(ListIterator=objects.begin(); ListIterator!=objects.end();)
        {
            if( (*ListIterator)->isToDelete )
            {
                ListIterator = objects.erase(ListIterator);
                delete *ListIterator;
            }
            else {
                ++ListIterator;
            }
        }
    objectHasBeenDeleted = false;
    }
}

দুটি বস্তুর একটি (পয়েন্টার টু) ভেক্টর ব্যবহার করে।

std::vector<object*> *objects;

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

void container::update()
{
    if (objectHasBeenDeleted)
    {
        std::vector<object*> *newVector;
        unsigned long i;
        for (i = 0; i < objects->size(); i++)
        {
            if (!objects->at(i)->isToDelete)
            {
                newVector->push_back(objects->at(i));
            }
        }
        delete objects;
        objects = newVector;
        objectHasBeenDeleted = false;
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.