গেমঅবজেক্ট শ্রেণীর বাইরে রেন্ডার যুক্তিকে সরিয়ে দেওয়ার কৌশল


10

গেমস তৈরি করার সময় আপনি প্রায়শই নিম্নলিখিত গেমের অবজেক্ট তৈরি করেন যা থেকে সমস্ত সত্তা উত্তরাধিকার সূত্রে:

public class GameObject{
    abstract void Update(...);
    abstract void Draw(...);
}

সুতরাং আপনি লুপ আপডেট করে আপনি সমস্ত গেমের অবজেক্টের উপর পুনরাবৃত্তি করেন এবং তাদের রাষ্ট্র পরিবর্তন করার সুযোগ দেন, তারপরে পরবর্তী অঙ্কনের লুপে আপনি সমস্ত গেমের বস্তুগুলির উপর আবার পুনরাবৃত্তি করেন এবং তাদেরকে নিজের আঁকানোর সুযোগ দেন।

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

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

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

সুতরাং আমি ক্ষতিতে আছি এবং ভাল সমাধানের কথা ভাবতে পারি না। আমি এমভিসির নীতিগুলি ব্যবহার করার চেষ্টা করেছি এবং অতীতে গেমগুলিতে এটি কীভাবে ব্যবহার করা যায় সে সম্পর্কে আমার কিছু ধারণা ছিল তবে সাম্প্রতিক সময়ে এটি যেমনটি ভেবেছিল তেমনটি কার্যকর বলে মনে হয় না। আপনারা সকলেই কীভাবে এই সমস্যাটি মোকাবেলা করবেন তা জানতে আগ্রহী।

যাইহোক, আসুন পুনরুদ্ধার করা যাক, আমি নিম্নলিখিত ডিজাইন লক্ষ্যগুলি কীভাবে অর্জন করতে পারি তাতে আগ্রহী।

  • গেম অবজেক্টে কোনও রেন্ডারিং লজিক নেই
  • গেম অবজেক্ট এবং রেন্ডার ইঞ্জিনের মধ্যে আলগা মিলন
  • সমস্ত জ্ঞান সরবরাহকারী নেই
  • রেন্ডার ইঞ্জিনগুলির মধ্যে রানটাইম স্যুইচিং

আদর্শ প্রকল্পের সেটআপটি একটি পৃথক 'গেম লজিক' হবে এবং লজিক প্রজেক্ট রেন্ডার করবে যার একে অপরকে রেফারেন্স দেওয়ার দরকার নেই।

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

উত্তর:


7

হতাশার জন্য একটি দ্রুত প্রথম পদক্ষেপ:

গেম অবজেক্টগুলি তাদের ভিজ্যুয়ালগুলি কীসের একটি শনাক্তকারীকে নির্দেশ করে তবে ডেটা নয়, আসুন স্ট্রিংয়ের মতো সাধারণ কিছু। উদাহরণ: "মানব_মহলে"

রেন্ডারার "মানব_মহলে" রেফারেন্সগুলি লোড করা এবং বজায় রাখতে এবং ব্যবহারের জন্য একটি হ্যান্ডেল অবজেক্টে ফিরে যাওয়ার জন্য দায়ী।

ভয়াবহ সিউডোকোডের উদাহরণ:

GameObject( initialization parameters )
  me.render_handle = Renderer_Create( parameters.render_string )

- elsewhere
Renderer_Create( string )

  new data handle = Resources_Load( string );
  return new data handle

- some time later
GameObject( something happens to me parameters )
  me.state = something.what_happens
  Renderer_ApplyState( me.render_handle, me.state.effect_type )

- some time later
Renderer_Render()
  for each renderable thing
    for each rendering back end
        setup graphics for thing.effect
        render it

- finally
GameObject_Destroy()
  Renderer_Destroy( me.render_handle )

এই গণ্ডগোলের জন্য দুঃখিত, যাইহোক আপনার শর্তগুলি সেই বাস্তব পরিবর্তনের দ্বারা খাঁটি ওওপি থেকে দূরে বাস্তব বিশ্বের বস্তুগুলির মতো বিষয়গুলিকে দেখার জন্য এবং দায়বদ্ধতার উপর ভিত্তি করে ওওপিতে রূপান্তরিত করে met

  • গেম অবজেক্টে কোনও রেন্ডারিং লজিক নেই (সম্পন্ন হয়েছে, সমস্ত বস্তু জানেন যে একটি হ্যান্ডেল তাই এটি নিজের উপর প্রভাব প্রয়োগ করতে পারে)
  • গেম অবজেক্টস এবং রেন্ডার ইঞ্জিনের মধ্যে আলগা সংযোগ (সম্পন্ন হয়ে গেছে, সমস্ত যোগাযোগ একটি বিমূর্ত হ্যান্ডেলের মাধ্যমে হয়, রাজ্যগুলি প্রয়োগ করা যেতে পারে এবং সেই রাজ্যগুলির সাথে কী করা যায় না)
  • সমস্ত জ্ঞান সরবরাহকারী নেই (সম্পন্ন হয়েছে, কেবল নিজের সম্পর্কে জানে)
  • সাধারণত রেন্ডার ইঞ্জিনগুলির মধ্যে রানটাইম স্যুইচিং (এটি রেন্ডারার_রেন্ডার () পর্যায়ে করা হয়, আপনাকে উভয় পিছনের প্রান্তটি লিখতে হবে)

ক্লাসগুলির একটি সাধারণ রিফ্যাক্টরিংয়ের বাইরে আপনি যে কীওয়ার্ডগুলি সন্ধান করতে পারেন সেগুলি হ'ল পুরানো মস্তিষ্কের গিয়ার্স স্পিনিংয়ের জন্য "সত্তা / উপাদান উপাদান" এবং "নির্ভরতা ইনজেকশন" এবং সম্ভাব্য "এমভিসি" জিইউআই নিদর্শনগুলি।


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

2

আমি আমার নিজের ইঞ্জিনের জন্য যা করেছি তা হ'ল সবকিছুকে মডিউলগুলিতে ভাগ করা। সুতরাং আমার GameObjectক্লাস রয়েছে এবং এটির একটি হ্যান্ডেল রয়েছে:

  • মডিউলপ্রিট - অঙ্কন স্প্রাইটস
  • মডিউলওপন - গুলি চালানো
  • ModuleScripttingBase - স্ক্রিপ্টিং
  • মডিউল পার্টিকেলস - কণা প্রভাব
  • মডিউলক্লিশন - সংঘর্ষ সনাক্তকরণ এবং প্রতিক্রিয়া

সুতরাং আমি একটি Playerক্লাস এবং একটি Bulletক্লাস আছে। উভয় থেকে প্রাপ্ত GameObjectএবং যোগ করা হয় Scene। তবে Playerনিম্নলিখিত মডিউলগুলি রয়েছে:

  • ModuleSprite
  • ModuleWeapon
  • ModuleParticles
  • ModuleCollision

এবং Bulletএই মডিউলগুলি রয়েছে:

  • ModuleSprite
  • ModuleCollision

জিনিসগুলিকে সংগঠিত করার এই পদ্ধতিটি "মৃত্যুর ডায়মন্ড" এড়িয়ে চলে যেখানে আপনার ক Vehicle, ক VehicleLandএবং একটি রয়েছে VehicleWaterএবং এখন আপনি একটি চান VehicleAmphibious। পরিবর্তে আপনার কাছে একটি Vehicleএবং এটিতে একটি ModuleWaterএবং একটি থাকতে পারে ModuleLand

যুক্ত বোনাস: আপনি বৈশিষ্ট্যের সেট ব্যবহার করে অবজেক্ট তৈরি করতে পারেন। আপনাকে যা জানার দরকার তা হ'ল বেসটাইপ (প্লেয়ার, শত্রু, বুলেট ইত্যাদি) এবং তারপরে সেই ধরণের আপনার প্রয়োজনীয় মডিউলগুলিতে হ্যান্ডলগুলি তৈরি করুন।

আমার দৃশ্যে, আমি নিম্নলিখিতগুলি করি:

  • Updateসমস্ত GameObjectহ্যান্ডলগুলির জন্য কল করুন ।
  • যাদের একটি ModuleCollisionহ্যান্ডেল রয়েছে তাদের জন্য সংঘর্ষের চেকিং এবং সংঘর্ষের প্রতিক্রিয়া করুন ।
  • পদার্থবিজ্ঞানের পরে তাদের চূড়ান্ত অবস্থান সম্পর্কে জানতে UpdatePostসকল GameObjectহ্যান্ডলদের কল করুন ।
  • তাদের পতাকা সেট আছে এমন বস্তুগুলি ধ্বংস করুন।
  • m_ObjectsCreatedতালিকা থেকে তালিকা থেকে নতুন অবজেক্ট যুক্ত করুন m_Objects

এবং আমি এটি আরও সংগঠিত করতে পারি: বস্তুর পরিবর্তে মডিউলগুলির দ্বারা। তারপরে আমি একটি তালিকা রেন্ডার করব ModuleSprite, একগুচ্ছ আপডেট ModuleScriptingBaseকরব এবং তালিকার সাথে সংঘর্ষ করব ModuleCollision


সর্বাধিক থেকে রচনা মত শোনাচ্ছে! খুব সুন্দর. যদিও আমি এখানে খুব বেশি রেন্ডারিং নির্দিষ্ট টিপস দেখতে পাচ্ছি না। আপনি কীভাবে এটি পরিচালনা করবেন, কেবলমাত্র বিভিন্ন মডিউল যুক্ত করে?
রায় টি।

হ্যাঁ. এটি এই ব্যবস্থার ক্ষয়ক্ষতি: যদি আপনার কোনও নির্দিষ্ট প্রয়োজন হয় GameObject(উদাহরণস্বরূপ স্প্রাইটসের "সাপ" রেন্ডার করার উপায়) আপনার হয় ModuleSpriteসেই নির্দিষ্ট কার্যকারিতার জন্য একটি শিশু তৈরি করতে হবে ( ModuleSpriteSnake) অথবা সম্পূর্ণ নতুন মডিউল যুক্ত করতে হবে ( ModuleSnake)। সৌভাগ্য যে তারা শুধুমাত্র পয়েন্টার, কিন্তু আমি কোডটি যেখানে দেখা করেছি GameObjectআক্ষরিক করেনি সবকিছু একটি বস্তু কাজ করতে পারে।
নাইট 666
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.