আমি একটি সত্তা সিস্টেমের বৈকল্পিক প্রয়োগ করছি যা এতে রয়েছে:
একটি সত্তা শ্রেণি যা আইডি থেকে সামান্য বেশি যা উপাদানগুলি একসাথে আবদ্ধ করে
একগুচ্ছ উপাদান শ্রেণীর যাতে কোনও "উপাদান যুক্তি" নেই, কেবলমাত্র ডেটা
সিস্টেম ক্লাসের একটি গুচ্ছ (ওরফে "সাবসিস্টেম", "পরিচালক")। এগুলি সমস্ত সত্তার লজিক প্রসেসিং করে। বেশিরভাগ বুনিয়াদি ক্ষেত্রে, সিস্টেমগুলি কেবলমাত্র তাদের সত্তায় আগ্রহী সেই সংস্থাগুলির একটি তালিকা খাঁজ করে এবং সেগুলির প্রতিটিটিতে একটি ক্রিয়া করে
একটি বার্তাচ্যানেল শ্রেণি অবজেক্ট যা সমস্ত গেম সিস্টেম দ্বারা ভাগ করা হয়। প্রতিটি সিস্টেম শোনার জন্য নির্দিষ্ট ধরণের বার্তায় সাবস্ক্রাইব করতে পারে এবং অন্যান্য সিস্টেমে বার্তা সম্প্রচার করতে চ্যানেলটি ব্যবহার করতে পারে
সিস্টেম বার্তা হ্যান্ডলিংয়ের প্রাথমিক রূপটি ছিল এরকম কিছু:
- প্রতিটি গেম সিস্টেমে ধারাবাহিকভাবে একটি আপডেট চালান
যদি কোনও সিস্টেম কোনও উপাদানকে কিছু করে এবং সেই ক্রিয়াটি অন্যান্য সিস্টেমে আগ্রহী হতে পারে তবে সিস্টেমটি একটি উপযুক্ত বার্তা প্রেরণ করে (উদাহরণস্বরূপ, সিস্টেম কলগুলি
messageChannel.Broadcast(new EntityMovedMessage(entity, oldPosition, newPosition))
যখনই কোনও সত্তা সরানো হবে)
নির্দিষ্ট বার্তায় সাবস্ক্রাইব করা প্রতিটি সিস্টেম এটির বার্তা হ্যান্ডলিং পদ্ধতি বলে
যদি কোনও সিস্টেম কোনও ইভেন্ট পরিচালনা করে এবং ইভেন্ট প্রসেসিং লজিকের জন্য অন্য একটি বার্তা সম্প্রচারিত করা প্রয়োজন, বার্তাটি তত্ক্ষণাত সম্প্রচারিত হয়ে যায় এবং বার্তা প্রক্রিয়াকরণের পদ্ধতিগুলির আরেকটি শৃঙ্খলা ডাকে 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);
}
}
}
কোডটি এর মতো প্রবাহিত হয় (ধরে নেওয়া যাক এটি প্রথম গেমের ফ্রেম নয়):
- সিস্টেমগুলি টাইমপ্যাসডমেজ প্রক্রিয়া শুরু করে
- ইনপুটহ্যান্ডিংসিস্টেম কী চাপকে সত্তা ক্রিয়ায় রূপান্তর করে (এই ক্ষেত্রে, একটি বাম তীর মুভওয়েস্ট ক্রিয়ায় রূপান্তরিত হয়)। সত্তা ক্রিয়াটি অ্যাকশনএক্সেক্টর উপাদানতে সঞ্চয় করা হয়
- সত্তা কর্মের প্রতিক্রিয়া হিসাবে অ্যাকশনএকসিচিউশন সিস্টেম , বার্তা সারিটির শেষের দিকে একটি মুভমেন্টডাইরেশনচেনজরিভেস্টড ম্যাসেজ যুক্ত করে
- মুভমেন্টসিস্টেমটি বেগ উপাদান উপাদান ডেটার উপর ভিত্তি করে সত্তা অবস্থান সরিয়ে দেয় এবং পজিশন চেঞ্জডেসেস বার্তাটি সারির শেষে যুক্ত করে। আন্দোলনটি পূর্ববর্তী ফ্রেমের গতিবেগের দিকনির্দেশ / গতিবেগ ব্যবহার করে করা হয় (আসুন উত্তরটি বলি)
- সিস্টেমগুলি টাইমপ্যাসডমেজ প্রক্রিয়া বন্ধ করে দেয়
- সিস্টেমগুলি মুভমেন্টডাইরেশনচেনজরিভেস্টড ম্যাসেজ প্রক্রিয়াকরণ শুরু করে
- মুভমেন্টসিস্টেম অনুরোধ অনুসারে সত্তার গতি / চলনের দিক পরিবর্তন করে
- সিস্টেমগুলি মুভমেন্টডাইরেশনচেনজরিভেস্টড ম্যাসেজ প্রক্রিয়াকরণ বন্ধ করে দেয়
- সিস্টেমগুলি পজিশন চেঞ্জডেসেস প্রক্রিয়া শুরু করে
- সংঘটন সনাক্তকরণ সিস্টেমটি সনাক্ত করে যে কোনও সত্তা সরে যাওয়ার কারণে এটি অন্য সত্তায় চলে গেছে (ট্যাঙ্কটি একটি দেয়ালের অভ্যন্তরে গেছে)। এটি কুইজে একটি কলিজিওনকুরিডমেসেজ যুক্ত করেছে
- সিস্টেমগুলি পজিশন চেঞ্জডেসেস প্রক্রিয়া বন্ধ করে দেয়
- সিস্টেমগুলি কলসিওকুরিডম্যাসেজ প্রক্রিয়া শুরু করে
- টান এবং প্রাচীর পৃথক করে সংঘর্ষে প্রতিক্রিয়া জানায় l যেহেতু প্রাচীর স্থির, কেবল ট্যাঙ্কটি সরানো হয়েছে। ট্যাঙ্কগুলির চলাচলের দিকটি ট্যাঙ্কটি কোথা থেকে এসেছে তা সূচক হিসাবে ব্যবহৃত হয়। এটি বিপরীত দিকে অফসেট হয়
বাউজি: যখন ট্যাঙ্কটি এই ফ্রেমটি সরিয়ে নিয়েছিল, তখন এটি পূর্ববর্তী ফ্রেম থেকে চলাচলের দিকটি ব্যবহার করে সরানো হয়েছিল, তবে যখন এটি পৃথক করা হচ্ছে তখন এই ফ্রেমটি থেকে চলার দিকটি ব্যবহৃত হয়েছিল, যদিও এটি ইতিমধ্যে আলাদা ছিল। এটি কিভাবে কাজ করা উচিত নয়!
এই বাগটি প্রতিরোধ করতে, পুরানো চলাফেরার দিকটি কোথাও সংরক্ষণ করা দরকার। আমি কেবলমাত্র এই নির্দিষ্ট বাগটি সংশোধন করার জন্য এটি কোনও উপাদানকে যুক্ত করতে পারি, তবে এই ক্ষেত্রে বার্তা পরিচালনার কিছু মৌলিকভাবে ভুল উপায় নির্দেশ করে না? বিভাজন সিস্টেমটি কোন চলনের দিকটি এটি ব্যবহার করে সেদিকে যত্ন নেওয়া উচিত? আমি কীভাবে এই সমস্যাটি মার্জিতভাবে সমাধান করতে পারি?
- তারা पहাগুলি দিয়ে কী করেছে তা দেখতে আপনি গামাডো / আর্টেমিসটি পড়তে চাইতে পারেন, কোন দিকটি আপনি যে সমস্যার মুখোমুখি হচ্ছেন তাতে পদক্ষেপ নেয়।
আসলে, আমি বেশ কিছুদিন ধরে আর্টেমিসের সাথে পরিচিত ছিলাম। এর উত্স কোডটি অনুসন্ধান করা হয়েছে, ফোরামগুলি পড়া ইত্যাদি But তবে আমি দেখেছি "দিকগুলি" কেবলমাত্র কয়েকটি জায়গায় উল্লেখ করা হয়েছে এবং যতদূর আমি এটি বুঝতে পেরেছি সেগুলি মূলত "সিস্টেমস" এর অর্থ। তবে আমি দেখতে পাচ্ছি না আর্টেমিস সাইড কীভাবে আমার কয়েকটি সমস্যার পদক্ষেপ নেয়। এটি বার্তা ব্যবহার করে না।
- আরও দেখুন: "সত্তা যোগাযোগ: বার্তা সারি বনাম প্রকাশ করুন / বনাম সিগন্যাল / স্লট সাবস্ক্রাইব করুন"
সত্তা সিস্টেম সম্পর্কিত আমি সমস্ত গেমদেব.স্ট্যাকেক্সচেঞ্জ প্রশ্ন ইতিমধ্যে পড়েছি। এইটি আমি যে সমস্যার মুখোমুখি হচ্ছি তা নিয়ে আলোচনা করে বলে মনে হচ্ছে না। আমি কিছু অনুপস্থিত করছি?
- দুটি ক্ষেত্রে পৃথকভাবে পরিচালনা করুন, গ্রিডটি আপডেট করার সাথে সংঘর্ষের ব্যবস্থার অংশ হিসাবে চলমান বার্তাগুলির উপর নির্ভর করার প্রয়োজন নেই
আপনি কি বোঝাতে চাচ্ছেন তা আমি নিশ্চিত নই. কলিজেনডিশনসিস্টেমের পুরানো বাস্তবায়নগুলি কেবলমাত্র একটি আপডেটে সংঘর্ষের জন্য পরীক্ষা করতে পারে (যখন একটি টাইমপ্যাসেডমেজ পরিচালনা করা হয়ে থাকে), তবে পারফরম্যান্সের কারণে আমাকে যতটা সম্ভব চেকগুলি হ্রাস করতে হয়েছিল। সুতরাং যখন কোনও সত্তা সরে যায় তখন আমি সংঘর্ষের পরীক্ষার দিকে চলে যাই (আমার গেমের বেশিরভাগ সত্তা স্থির থাকে)।