মন্তব্যে, আমি আমার উত্তর পুরানো উত্তরের একটি ঘনীভূত সংস্করণ পোস্ট করেছি:
ব্যবহার DrawableGameComponentপদ্ধতি স্বাক্ষর একটি একক সেট মধ্যে কেশ আপনি একটি নির্দিষ্ট অপরিবর্তিত রাখা ডাটা মডেল। এগুলি সাধারণত প্রাথমিকভাবে ভুল পছন্দ এবং লক-ইনটি উল্লেখযোগ্যভাবে কোডের বিবর্তনে বাধা দেয়।
এখানে আমি আমার বর্তমান প্রকল্প থেকে কিছু কোড পোস্ট করে বিষয়টি কেন তা বোঝানোর চেষ্টা করব।
গেম ওয়ার্ল্ডের অবস্থা বজায় রাখার মূল জিনিসটির এমন একটি Updateপদ্ধতি রয়েছে যা দেখতে এই রকম দেখাচ্ছে:
void Update(UpdateContext updateContext, MultiInputState currentInput)
Updateনেটওয়ার্কটিতে গেমটি চলছে কিনা তার উপর নির্ভর করে এখানে অনেকগুলি এন্ট্রি-পয়েন্ট রয়েছে । উদাহরণস্বরূপ, গেমের স্টেটটি সময়ের সাথে পূর্ববর্তী বিন্দুতে ফিরিয়ে দেওয়া এবং তারপরে পুনরায় সিমুলেটেড করা সম্ভব।
অতিরিক্ত কিছু আপডেটের মতো পদ্ধতি রয়েছে যেমন:
void PlayerJoin(int playerIndex, string playerName, UpdateContext updateContext)
গেমের রাজ্যের মধ্যে আপডেট করার জন্য অভিনেতাদের একটি তালিকা রয়েছে। তবে এটি একটি সাধারণ Updateকলের চেয়ে বেশি । পদার্থবিদ্যাকে পরিচালনা করার আগে এবং পরে অতিরিক্ত পাস রয়েছে। পিছনে ছড়িয়ে থাকা / অভিনেতাদের ধ্বংস, পাশাপাশি স্তরের রূপান্তরগুলির জন্য কিছু অভিনব জিনিস রয়েছে।
গেমের রাজ্যের বাইরেও একটি ইউআই সিস্টেম রয়েছে যা স্বতন্ত্রভাবে পরিচালনা করা দরকার। তবে ইউআইতে কিছু স্ক্রিনের নেটওয়ার্ক প্রসঙ্গে চালাতে সক্ষম হওয়াও দরকার।
অঙ্কনের জন্য, গেমের প্রকৃতির কারণে, এখানে একটি কাস্টম বাছাই এবং কুলিং সিস্টেম রয়েছে যা এই পদ্ধতিগুলি থেকে ইনপুট নেয়:
virtual void RegisterToDraw(SortedDrawList sortedDrawList, Definitions definitions)
virtual void RegisterShadow(ShadowCasterList shadowCasterList, Definitions definitions)
এবং তারপরে, এটি কী আঁকতে হবে তা একবার নির্ধারণ করে, স্বয়ংক্রিয়ভাবে কল করে:
virtual void Draw(DrawContext drawContext, int tag)
tagপ্যারামিটার প্রয়োজন বোধ করা হয় কারণ কিছু অভিনেতা অন্যান্য অভিনেতা সম্মুখের ধরে রাখতে পারেন - এবং তাই প্রয়োজন উভয় উপরের এবং নীচের অনুষ্ঠিত অভিনেতা আঁকা পাবে। বাছাই ব্যবস্থা নিশ্চিত করে যে এটি সঠিক ক্রমে ঘটে।
আঁকার জন্য মেনু সিস্টেমও রয়েছে। এবং গেমের আশেপাশে, এইচইউডির চারপাশে ইউআই আঁকার জন্য একটি হায়ারার্কিকাল সিস্টেম।
এখন সেই প্রয়োজনীয়তার সাথে তুলনা করুন যা DrawableGameComponentসরবরাহ করে:
public class DrawableGameComponent
{
public virtual void Update(GameTime gameTime);
public virtual void Draw(GameTime gameTime);
public int UpdateOrder { get; set; }
public int DrawOrder { get; set; }
}
DrawableGameComponentআমি উপরে বর্ণিত সিস্টেমটি ব্যবহার করে কোনও সিস্টেম থেকে পাওয়ার কোনও যুক্তিসঙ্গত উপায় নেই । (এবং এগুলি এমনকি সামান্য জটিলতার গেমের জন্য অস্বাভাবিক প্রয়োজনীয়তা নয়)।
এছাড়াও, এটি লক্ষ করা খুব জরুরী যে প্রকল্পগুলির শুরুতে এই প্রয়োজনীয়তাগুলি কেবল স্প্রিং-আপ করেনি। এগুলি বহু মাস ধরে উন্নয়নের কাজ করেছে।
লোকেরা সাধারণত যা করে, যদি তারা DrawableGameComponentরুটটি শুরু করে, তবে তারা কি হ্যাকগুলি তৈরি করা শুরু করে:
পদ্ধতিগুলি যুক্ত করার পরিবর্তে তারা তাদের নিজস্ব বেস ধরণের কিছু কুরুচিপূর্ণ ডাউন কাস্টিং করে (কেন কেবল এটি সরাসরি ব্যবহার করবেন না?)।
বাছাই এবং আহ্বানের জন্য কোডটি প্রতিস্থাপনের পরিবর্তে Draw/ Updateফ্লাইয়ের ক্রম সংখ্যা পরিবর্তন করতে তারা কিছু খুব ধীর গতি সম্পন্ন করে।
এবং সর্বোপরি সবচেয়ে খারাপ: পদ্ধতিগুলিতে পরামিতিগুলি যুক্ত করার পরিবর্তে, তারা মেমরির অবস্থানগুলিতে "পরামিতি" "পাস" শুরু করে যা স্ট্যাক নয় (এর Servicesজন্য ব্যবহার জনপ্রিয়)। এটি সংশ্লেষযুক্ত, ত্রুটি-প্রবণ, ধীর, ভঙ্গুর, খুব কমই থ্রেড-নিরাপদ এবং আপনি যদি নেটওয়ার্কিং যুক্ত করেন, বাহ্যিক সরঞ্জাম তৈরি করেন এবং এই জাতীয় কিছু সমস্যা হয়ে দাঁড়ানোর সম্ভাবনা রয়েছে।
এটি কোডটিকে পুনরায় ব্যবহার আরও শক্ত করে তোলে , কারণ এখন আপনার নির্ভরতাগুলি এপিআই বাউন্ডারে প্রকাশের পরিবর্তে "উপাদান" এর মধ্যে লুকিয়ে রয়েছে।
অথবা, তারা প্রায় দেখতে পাচ্ছেন যে এগুলি কতটা ক্রেজি এবং DrawableGameComponentএই সমস্যাগুলি ঘিরে কাজ করার জন্য "ম্যানেজার" এর কাজ শুরু করে। "ম্যানেজার" সীমানায় এখনও তাদের এই সমস্যাগুলি বাদে।
অবিচ্ছিন্নভাবে এই "পরিচালকদের" কাঙ্ক্ষিত ক্রমে একাধিক পদ্ধতি কল দিয়ে প্রতিস্থাপন করা যেতে পারে। অন্য যে কোনও কিছুই অতিরিক্ত জটিল।
অবশ্যই, আপনি একবার এই হ্যাকগুলিকে নিয়োগ দেওয়া শুরু করলে, আপনি যখন সরবরাহ করেন তার চেয়ে আরও বেশি প্রয়োজন অনুধাবন করার পরে এই হ্যাকগুলি পূর্বাবস্থায় আনতে সত্যিকারের কাজ লাগে DrawableGameComponent। আপনি " লক ইন " হয়ে যান। এবং প্রলোভনটি প্রায়শই হ্যাকগুলির উপরে গাদা চালিয়ে যাওয়া অব্যাহত থাকে - যা বাস্তবে আপনাকে হতাশ করে তুলবে এবং তুলনামূলক সরল খেলাগুলিতে আপনি যে ধরণের গেমস তৈরি করতে পারবেন তা সীমাবদ্ধ রাখবে।
অনেক লোক এই স্থানে পৌঁছেছে এবং তাদের কাছে একটি দর্শনীয় প্রতিক্রিয়া রয়েছে বলে মনে হয় - সম্ভবত কারণ তারা ব্যবহার করে DrawableGameComponentএবং "ভুল" বলে স্বীকার করতে চায় না। সুতরাং তারা এটিকে ল্যাচ করে যে এটি "কাজ" করা কমপক্ষে সম্ভব ।
অবশ্যই এটা হতে পারে তৈরি "কাজ" করুন! আমরা প্রোগ্রামাররা - অস্বাভাবিক সংযমের মধ্যে জিনিসগুলি তৈরি করা কার্যত আমাদের কাজ। তবে এই সংযম প্রয়োজনীয়, দরকারী বা যৌক্তিক নয় ...
বিশেষত যা উদ্বেগজনক তা হ'ল এটি হ'ল আশ্চর্যজনকভাবে এই পুরো বিষয়টিটি পাশ-পদক্ষেপের পক্ষে তুচ্ছ। এখানে, আমি আপনাকে কোডটিও দেব:
public class Actor
{
public virtual void Update(GameTime gameTime);
public virtual void Draw(GameTime gameTime);
}
List<Actor> actors = new List<Actor>();
foreach(var actor in actors)
actor.Update(gameTime);
foreach(var actor in actors)
actor.Draw(gameTime);
(এটা সরল অনুযায়ী বাছাই মধ্যে যোগ করার জন্য DrawOrderএবং UpdateOrder। এক সহজ উপায় দুই তালিকা, এবং ব্যবহার বজায় রাখা হয় List<T>.Sort()। এছাড়া হ্যান্ডেল তুচ্ছ হয় Load/ UnloadContent।)
এটা তোলে গুরুত্বপূর্ণ নয় কি যে কোড আসলে হয় । কী গুরুত্বপূর্ণ তা হল আমি তুচ্ছভাবে এটি সংশোধন করতে পারি ।
যখন আমি বুঝতে পারি যে আমার আলাদা টাইমিং সিস্টেমের প্রয়োজন gameTime, বা আমার আরও বেশি পরামিতি (বা UpdateContextএটিতে প্রায় 15 টি জিনিস রয়েছে এমন একটি সামগ্রিক ) প্রয়োজন, বা অঙ্কনের জন্য আমার সম্পূর্ণ আলাদা অর্ডার অফ-অপারেশন প্রয়োজন, বা আমার কিছু অতিরিক্ত পদ্ধতি প্রয়োজন বিভিন্ন আপডেট পাসের জন্য, আমি কেবল এগিয়ে যেতে পারি এবং এটি করতে পারি ।
এবং আমি তা অবিলম্বে এটি করতে পারেন। আমার কোডটি বাছাইয়ের বিষয়ে DrawableGameComponentআমার ত্রুটি করার দরকার নেই । বা আরও খারাপ: এটি এমন কোনও উপায়ে হ্যাক করুন যা পরের বার যখন এমন প্রয়োজনের আশপাশে আসে তখন আরও শক্ত হয়ে যায়।
সত্যিই কেবলমাত্র একটি দৃশ্য রয়েছে যেখানে এটি ব্যবহার করা ভাল পছন্দ DrawableGameComponent: এবং এটি হ'ল যদি আপনি XNA এর জন্য আক্ষরিকভাবে ড্রাগ-ড্রাগ-ড্রপ-উপাদান-শৈলীর মিডওয়্যারের তৈরি এবং প্রকাশ করছেন ing যা এর আসল উদ্দেশ্য ছিল। কোনটি - আমি যুক্ত করব - কেউ করছে না!
(একইভাবে, কাস্টম সামগ্রীর ধরণের তৈরি করার সময় এটি ব্যবহার করার জন্য কেবল সত্যটি উপলব্ধি করেServicesContentManager ))