কীভাবে কোনও উপাদান ভিত্তিক সত্তা সিস্টেমে বার্তা হ্যান্ডলিং সঠিকভাবে প্রয়োগ করা যায়?


30

আমি একটি সত্তা সিস্টেমের বৈকল্পিক প্রয়োগ করছি যা এতে রয়েছে:

  • একটি সত্তা শ্রেণি যা আইডি থেকে সামান্য বেশি যা উপাদানগুলি একসাথে আবদ্ধ করে

  • একগুচ্ছ উপাদান শ্রেণীর যাতে কোনও "উপাদান যুক্তি" নেই, কেবলমাত্র ডেটা

  • সিস্টেম ক্লাসের একটি গুচ্ছ (ওরফে "সাবসিস্টেম", "পরিচালক")। এগুলি সমস্ত সত্তার লজিক প্রসেসিং করে। বেশিরভাগ বুনিয়াদি ক্ষেত্রে, সিস্টেমগুলি কেবলমাত্র তাদের সত্তায় আগ্রহী সেই সংস্থাগুলির একটি তালিকা খাঁজ করে এবং সেগুলির প্রতিটিটিতে একটি ক্রিয়া করে

  • একটি বার্তাচ্যানেল শ্রেণি অবজেক্ট যা সমস্ত গেম সিস্টেম দ্বারা ভাগ করা হয়। প্রতিটি সিস্টেম শোনার জন্য নির্দিষ্ট ধরণের বার্তায় সাবস্ক্রাইব করতে পারে এবং অন্যান্য সিস্টেমে বার্তা সম্প্রচার করতে চ্যানেলটি ব্যবহার করতে পারে

সিস্টেম বার্তা হ্যান্ডলিংয়ের প্রাথমিক রূপটি ছিল এরকম কিছু:

  1. প্রতিটি গেম সিস্টেমে ধারাবাহিকভাবে একটি আপডেট চালান
  2. যদি কোনও সিস্টেম কোনও উপাদানকে কিছু করে এবং সেই ক্রিয়াটি অন্যান্য সিস্টেমে আগ্রহী হতে পারে তবে সিস্টেমটি একটি উপযুক্ত বার্তা প্রেরণ করে (উদাহরণস্বরূপ, সিস্টেম কলগুলি

    messageChannel.Broadcast(new EntityMovedMessage(entity, oldPosition, newPosition))

    যখনই কোনও সত্তা সরানো হবে)

  3. নির্দিষ্ট বার্তায় সাবস্ক্রাইব করা প্রতিটি সিস্টেম এটির বার্তা হ্যান্ডলিং পদ্ধতি বলে

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

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

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

কিছু ক্ষেত্রে এটি সমস্যার সৃষ্টি করে কারণ ঘরের সামগ্রীগুলি (সি # তে সত্তা সামগ্রীর জেনেরিক তালিকা) সেগুলি পুনরাবৃত্ত হওয়ার সময় সংশোধন হয়ে যায়, ফলে এটির দ্বারা একটি ব্যতিক্রম ছুঁড়ে ফেলা হয়।

সুতরাং ... সংঘর্ষের জন্য এটি পরীক্ষা করার সময় আমি কীভাবে সংঘর্ষের সিস্টেমটিকে বাধা দেওয়া থেকে আটকাতে পারি?

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

আমি যা চেষ্টা করেছি:

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

সম্পাদনা করুন - প্রশ্নের উত্তরসমূহ, মন্তব্যসমূহ:

  • সংঘর্ষের সিস্টেমটি তার উপর পুনরাবৃত্তি হওয়ার সময় কে ঘরের বিষয়বস্তু পরিবর্তন করে?

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

  • আপনি কি বিশ্বব্যাপী বহির্গামী বার্তার কাতারে কাজ করতে পারবেন না?

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

public void Update(int deltaTime)
{   
    m_messageQueue.Enqueue(new TimePassedMessage(deltaTime));
    while (m_messageQueue.Count > 0)
    {
        Message message = m_messageQueue.Dequeue();
        this.Broadcast(message);
    }
}

private void Broadcast(Message message)
{       
    if (m_messageListenersByMessageType.ContainsKey(message.GetType()))
    {
        // NOTE: all IMessageListener objects here are systems.
        List<IMessageListener> messageListeners = m_messageListenersByMessageType[message.GetType()];
        foreach (IMessageListener listener in messageListeners)
        {
            listener.ReceiveMessage(message);
        }
    }
}

কোডটি এর মতো প্রবাহিত হয় (ধরে নেওয়া যাক এটি প্রথম গেমের ফ্রেম নয়):

  1. সিস্টেমগুলি টাইমপ্যাসডমেজ প্রক্রিয়া শুরু করে
  2. ইনপুটহ্যান্ডিংসিস্টেম কী চাপকে সত্তা ক্রিয়ায় রূপান্তর করে (এই ক্ষেত্রে, একটি বাম তীর মুভওয়েস্ট ক্রিয়ায় রূপান্তরিত হয়)। সত্তা ক্রিয়াটি অ্যাকশনএক্সেক্টর উপাদানতে সঞ্চয় করা হয়
  3. সত্তা কর্মের প্রতিক্রিয়া হিসাবে অ্যাকশনএকসিচিউশন সিস্টেম , বার্তা সারিটির শেষের দিকে একটি মুভমেন্টডাইরেশনচেনজরিভেস্টড ম্যাসেজ যুক্ত করে
  4. মুভমেন্টসিস্টেমটি বেগ উপাদান উপাদান ডেটার উপর ভিত্তি করে সত্তা অবস্থান সরিয়ে দেয় এবং পজিশন চেঞ্জডেসেস বার্তাটি সারির শেষে যুক্ত করে। আন্দোলনটি পূর্ববর্তী ফ্রেমের গতিবেগের দিকনির্দেশ / গতিবেগ ব্যবহার করে করা হয় (আসুন উত্তরটি বলি)
  5. সিস্টেমগুলি টাইমপ্যাসডমেজ প্রক্রিয়া বন্ধ করে দেয়
  6. সিস্টেমগুলি মুভমেন্টডাইরেশনচেনজরিভেস্টড ম্যাসেজ প্রক্রিয়াকরণ শুরু করে
  7. মুভমেন্টসিস্টেম অনুরোধ অনুসারে সত্তার গতি / চলনের দিক পরিবর্তন করে
  8. সিস্টেমগুলি মুভমেন্টডাইরেশনচেনজরিভেস্টড ম্যাসেজ প্রক্রিয়াকরণ বন্ধ করে দেয়
  9. সিস্টেমগুলি পজিশন চেঞ্জডেসেস প্রক্রিয়া শুরু করে
  10. সংঘটন সনাক্তকরণ সিস্টেমটি সনাক্ত করে যে কোনও সত্তা সরে যাওয়ার কারণে এটি অন্য সত্তায় চলে গেছে (ট্যাঙ্কটি একটি দেয়ালের অভ্যন্তরে গেছে)। এটি কুইজে একটি কলিজিওনকুরিডমেসেজ যুক্ত করেছে
  11. সিস্টেমগুলি পজিশন চেঞ্জডেসেস প্রক্রিয়া বন্ধ করে দেয়
  12. সিস্টেমগুলি কলসিওকুরিডম্যাসেজ প্রক্রিয়া শুরু করে
  13. টান এবং প্রাচীর পৃথক করে সংঘর্ষে প্রতিক্রিয়া জানায় l যেহেতু প্রাচীর স্থির, কেবল ট্যাঙ্কটি সরানো হয়েছে। ট্যাঙ্কগুলির চলাচলের দিকটি ট্যাঙ্কটি কোথা থেকে এসেছে তা সূচক হিসাবে ব্যবহৃত হয়। এটি বিপরীত দিকে অফসেট হয়

বাউজি: যখন ট্যাঙ্কটি এই ফ্রেমটি সরিয়ে নিয়েছিল, তখন এটি পূর্ববর্তী ফ্রেম থেকে চলাচলের দিকটি ব্যবহার করে সরানো হয়েছিল, তবে যখন এটি পৃথক করা হচ্ছে তখন এই ফ্রেমটি থেকে চলার দিকটি ব্যবহৃত হয়েছিল, যদিও এটি ইতিমধ্যে আলাদা ছিল। এটি কিভাবে কাজ করা উচিত নয়!

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

  • তারা पहাগুলি দিয়ে কী করেছে তা দেখতে আপনি গামাডো / আর্টেমিসটি পড়তে চাইতে পারেন, কোন দিকটি আপনি যে সমস্যার মুখোমুখি হচ্ছেন তাতে পদক্ষেপ নেয়।

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

  • আরও দেখুন: "সত্তা যোগাযোগ: বার্তা সারি বনাম প্রকাশ করুন / বনাম সিগন্যাল / স্লট সাবস্ক্রাইব করুন"

সত্তা সিস্টেম সম্পর্কিত আমি সমস্ত গেমদেব.স্ট্যাকেক্সচেঞ্জ প্রশ্ন ইতিমধ্যে পড়েছি। এইটি আমি যে সমস্যার মুখোমুখি হচ্ছি তা নিয়ে আলোচনা করে বলে মনে হচ্ছে না। আমি কিছু অনুপস্থিত করছি?

  • দুটি ক্ষেত্রে পৃথকভাবে পরিচালনা করুন, গ্রিডটি আপডেট করার সাথে সংঘর্ষের ব্যবস্থার অংশ হিসাবে চলমান বার্তাগুলির উপর নির্ভর করার প্রয়োজন নেই

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


এমন কিছু আছে যা আমার কাছে পরিষ্কার নয়। সংঘর্ষের সিস্টেমটি তার উপর পুনরাবৃত্তি হওয়ার সময় কে ঘরের বিষয়বস্তু পরিবর্তন করে?
পল মানতা

আপনি কি বিশ্বব্যাপী বহির্গামী বার্তার কাতারে কাজ করতে পারবেন না? সুতরাং সেখানে সমস্ত বার্তা কোনও সিস্টেম সম্পন্ন হওয়ার পরে প্রত্যেক বার প্রেরণ করা হয়, এর মধ্যে রয়েছে সিস্টেম স্ব-বিনষ্টকরণ।
রায় টি।

আপনি যদি এই বিভ্রান্ত নকশা রাখতে চান তবে আপনাকে অবশ্যই @ রয়টি অনুসরণ করতে হবে। আপনার পরামর্শ, এটি আপনার ক্রম সমস্যাটি পরিচালনা করার একমাত্র উপায় (জটিল, সময় ভিত্তিক বার্তা ছাড়াই)। তারা पहাগুলি দিয়ে কী করেছে তা দেখতে আপনি গামাডো / আর্টেমিসটি পড়তে চাইতে পারেন, কোন দিকটি আপনি যে সমস্যার মুখোমুখি হচ্ছেন তাতে পদক্ষেপ নেয়।
প্যাট্রিক হিউজেস


2
আপনি শিখতে চাইতে পারেন কীভাবে অ্যাক্সাম সিটিপি ডাউনলোড করে এবং কিছু কোড সংকলন করে এটি করেছিলেন - এবং তারপরে আইএলএসপিএস ব্যবহার করে ইঞ্জিনিয়ারিংয়ের ফলাফলটি সি # তে বিপরীত করলেন। অভিনেতার মডেল ভাষাগুলির মেসেজ পাস করা একটি গুরুত্বপূর্ণ বৈশিষ্ট্য এবং আমি নিশ্চিত যে মাইক্রোসফ্ট জানে যে তারা কী করছে - তাই আপনি তাদের খুঁজে পেতে পারেন যে তাদের 'সেরা' বাস্তবায়ন হয়েছে।
জোনাথন ডিকিনসন

উত্তর:


12

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

আমি আপনার প্রশ্নের শব্দগুচ্ছ বুঝতে পারার সাথে সাথে আপনার সংঘর্ষের সিস্টেমটি আপডেট করার পদ্ধতিটি বর্তমানে নীচের মত দেখতে ব্যাপকভাবে দেখায়।

for each possible collision
    check for collision
    handle collision
    modify collision world to reflect change // exception happens here

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

for each possible collision
    check for collision, record it if a collision occurs

for each found collision
    handle collision, record the collision response (delete object, ignore, etc.)

for each collision response
    modify collision world according to response

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

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


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

11

কীভাবে কোনও উপাদান ভিত্তিক সত্তা সিস্টেমে বার্তা হ্যান্ডলিং সঠিকভাবে প্রয়োগ করা যায়?

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

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

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

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

এটি সম্পর্কে চিন্তা করুন: এটি সিঙ্ক্রোনাসের প্রকৃতির (সাথে সাথে কিছু ক্রিয়াকলাপের সমস্ত প্রতিক্রিয়া অবিলম্বে পরিচালনা করুন) এবং বার্তা সিস্টেম (প্রেরকের কাছ থেকে রিসিভারটি ডিকপলিং করে তাই প্রেরক জানেন না যে কারা প্রতিক্রিয়া দেখিয়েছেন) আপনি সহজেই সক্ষম হবেন না যেমন লুপ স্পট। আমি যা বলছি তা হ'ল: এই ধরণের স্ব-পরিবর্তনকারী পুনরাবৃত্তিটি পরিচালনা করার জন্য প্রস্তুত থাকুন। এর নকশা "ডিজাইন দ্বারা"। ;-)

সংঘর্ষের জন্য এটি পরীক্ষা করার সময় আমি কীভাবে সংঘর্ষের সিস্টেমটিকে বাধাগ্রস্ত হওয়া থেকে আটকাতে পারি?

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

সমস্যা: যদি সিস্টেম এ এর ​​বি কাতারে কোনও বার্তা যুক্ত করে, সিস্টেম বি এর পরে সিস্টেম এ-এর তুলনায় আপডেট করা হয় (একই গেমের ফ্রেমে); অন্যথায় এটি বার্তাটি পরবর্তী গেম ফ্রেমটি প্রক্রিয়াজাত করে (কিছু সিস্টেমের জন্য কাম্য নয়)

সহজ:

যখন (! queue.empty ()) {queue.pop ()। হ্যান্ডেল (); }

কোনও বার্তা না পাওয়া পর্যন্ত কেবল সারি চালিয়ে যান। (আপনি যদি এখন "অন্তহীন লুপ" চেঁচান, মনে রাখবেন যে পরবর্তী ফ্রেমে দেরী হলে আপনার সম্ভবত সম্ভবত "বার্তা স্প্যামিং" হিসাবে এই সমস্যাটি হবে less অন্তহীন লুপগুলি সনাক্ত করার জন্য আপনি বুদ্ধিমান সংখ্যার পুনরাবৃত্তি জন্য,) যদি আপনি এটির মতো অনুভব করেন;))


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

5

আপনি যদি বাস্তবে ইসিএসের ডেটা-ওরিয়েন্টড-ডিজাইন প্রকৃতিটি ব্যবহার করার চেষ্টা করছেন তবে আপনি এটির সর্বাধিক ডিওডি পদ্ধতি সম্পর্কে ভাবতে চাইতে পারেন।

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

উদাহরণস্বরূপ, কলিজন সিস্টেম সংঘর্ষের ঘটনায় পূর্ণ একটি বাফার তৈরি করবে। সংঘর্ষের পরে চালিত অন্য যে কোনও সিস্টেমের পরে তালিকাটি পুনরাবৃত্তি করতে পারে এবং প্রয়োজনীয়গুলি প্রক্রিয়া করতে পারে।

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

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


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

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

এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। এ সম্পর্কে যাওয়ার একটি সহজ উপায় হ'ল কেবল একটি নতুন ধরণের উপাদান তৈরি করা, উদাহরণস্বরূপ কলিজারেসলভেবল যা সংঘর্ষের পরে জিনিসগুলি করতে আগ্রহী প্রতিটি সিস্টেম প্রক্রিয়া করবে। যা ড্রাকের প্রস্তাবের সাথে পুরোপুরি ফিট হবে, তবে প্রতিটি মহকুমার লুপের জন্য একটি ব্যবস্থা রয়েছে।
ব্যবহারকারীর 6363
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.