শিরোনামটি ইচ্ছাকৃতভাবে হাইপারবোলিক এবং এটি কেবল প্যাটার্নটির সাথে আমার অনভিজ্ঞ হতে পারে তবে আমার যুক্তিটি এখানে:
সত্তা বাস্তবায়নের "সাধারণ" বা তর্কযুক্ত যুক্তিযুক্ত সহজ উপায় হ'ল তাদের অবজেক্ট হিসাবে প্রয়োগ করে এবং সাধারণ আচরণ সাবক্লাসিং করে। এটি "এর EvilTree
একটি সাবক্লাস Tree
নাকি Enemy
?" এর ক্লাসিক সমস্যার দিকে পরিচালিত করে । আমরা যদি একাধিক উত্তরাধিকারের অনুমতি দিই, তবে হীরকের সমস্যা দেখা দেয়। আমরা পরিবর্তে সম্মিলিত কার্যকারিতা টানতে Tree
এবং Enemy
আরও upশ্বরের শ্রেণীর দিকে পরিচালিত করে এমন শ্রেণিবিন্যাসকে আরও উপরে তুলে ধরতে পারি, বা আমরা আমাদের Tree
ও Entity
শ্রেণিতে ইচ্ছাকৃত আচরণটি ছেড়ে দিতে পারি (চরম ক্ষেত্রে তাদের ইন্টারফেস তৈরি করে) যাতে EvilTree
এটি নিজে প্রয়োগ করতে পারে - যা বাড়ে কোড সদৃশ যদি আমরা কখনও একটি SomewhatEvilTree
।
সত্তা-অংশীদার সিস্টেমগুলি এই সমস্যাটি সমাধান করতে চেষ্টা করে Tree
এবং Enemy
বস্তুকে বিভিন্ন উপাদানগুলিতে বিভক্ত করে - বলে Position
, Health
এবং AI
- এবং প্রয়োগ করে সিস্টেমগুলি যেমন AISystem
এআইয়ের সিদ্ধান্ত অনুযায়ী কোনও এন্টিটির অবস্থান পরিবর্তন করে। এখন পর্যন্ত এত ভাল তবে যদি EvilTree
কোনও পাওয়ারআপ বাছাই করতে পারে এবং ক্ষয়ক্ষতি ডিল করতে পারে? প্রথমে আমাদের একটি CollisionSystem
এবং একটি প্রয়োজন DamageSystem
(সম্ভবত আমাদের ইতিমধ্যে এটি রয়েছে)। CollisionSystem
চাহিদার সঙ্গে যোগাযোগ করতে DamageSystem
: প্রত্যেক সময় দুটি জিনিস ধাক্কা লাগা CollisionSystem
একটি বার্তা পাঠায় DamageSystem
স্বাস্থ্য তাই এটি বিয়োগ করতে পারেন। ক্ষয়টি পাওয়ারআপগুলি দ্বারাও প্রভাবিত হয় তাই আমাদের এটি অন্য কোথাও সংরক্ষণ করা দরকার। PowerupComponent
সত্ত্বার সাথে আমরা সংযুক্ত করে কি আমরা একটি নতুন তৈরি করি? কিন্তু তারপরDamageSystem
এটি এমন কিছু সম্পর্কে জানার দরকার যা এটি সম্পর্কে কিছুই জানত না - সর্বোপরি এমন কিছু জিনিস রয়েছে যা ক্ষতির মুখোমুখি হয় যা পাওয়ার আপগুলি তুলতে পারে না (যেমন ক Spike
)। আমরা কি এই উত্তরটির অনুরূপ ক্ষতির গণনার জন্য ব্যবহৃত PowerupSystem
একটিটি সংশোধন করার অনুমতি দিই ? তবে এখন দুটি সিস্টেম একই ডেটা অ্যাক্সেস করে। আমাদের খেলাটি আরও জটিল হওয়ার সাথে সাথে এটি একটি অদম্য নির্ভরতা গ্রাফ হয়ে উঠবে যেখানে উপাদানগুলি অনেকগুলি সিস্টেমের মধ্যে ভাগ করা হয়। এই মুহুর্তে আমরা কেবল গ্লোবাল স্ট্যাটিক ভেরিয়েবলগুলি ব্যবহার করতে পারি এবং সমস্ত বয়লারপ্লেট থেকে মুক্তি পেতে পারি।StatComponent
এটি সমাধানের কার্যকর উপায় আছে কি? আমার একটি ধারণা ছিল উপাদানগুলিকে কিছু নির্দিষ্ট কাজ করতে দেওয়া, উদাহরণস্বরূপ, StatComponent
attack()
যা কেবলমাত্র একটি পূর্ণসংখ্যকে ডিফল্টরূপে দেয় তবে পাওয়ারআপ হওয়ার পরে রচনা করা যায়:
attack = getAttack compose powerupBy(20) compose powerdownBy(40)
এটি attack
একাধিক সিস্টেম দ্বারা অ্যাক্সেস করা উপাদানগুলিতে সংরক্ষণ করতে হবে এমন সমস্যাটি সমাধান করে না তবে কমপক্ষে আমি সঠিকভাবে ফাংশনগুলি টাইপ করতে পারতাম যদি আমার কাছে এমন ভাষা থাকে যা একে যথেষ্ট সমর্থন করে:
// In StatComponent
type Strength = PrePowerup | PostPowerup
type Damage = Int
type PrePowerup = Int
type PostPowerup = Int
attack: Strength = getAttack //default value, can be changed by systems
getAttack: PrePowerup
// these functions can be defined in other components or in PowerupSystems
powerupBy: Strength -> PostPowerup
powerdownBy: Strength -> PostPowerup
subtractArmor: Strength -> Damage
// in DamageSystem
dealDamage: Damage -> () = attack compose subtractArmor compose hurtSomeEntity
এই পদ্ধতিতে আমি কমপক্ষে সিস্টেম দ্বারা যুক্ত বিভিন্ন ফাংশনগুলির সঠিক ক্রমটির গ্যারান্টি দিচ্ছি। যাইহোক, মনে হচ্ছে আমি দ্রুত এখানে কার্যকরী প্রতিক্রিয়াশীল প্রোগ্রামিংয়ের কাছে পৌঁছে যাচ্ছি তাই আমি নিজেকে জিজ্ঞাসা করি যে পরিবর্তে আমার প্রথম থেকেই এটি ব্যবহার করা উচিত ছিল না (আমি কেবল এফআরপিতে দেখেছি, তাই আমি এখানে ভুল হতে পারি)। আমি দেখতে পেয়েছি যে ইসিএস জটিল শ্রেণীর শ্রেণিবিন্যাসের তুলনায় একটি উন্নতি, তবে আমি নিশ্চিত নই যে এটি আদর্শ।
এর আশেপাশে কোন সমাধান আছে কি? ইসিএসকে আরও পরিষ্কারভাবে ডিকুয়াল করতে আমি কোনও কার্যকারিতা / প্যাটার্ন অনুপস্থিত রয়েছি? এফআরপি কি এই সমস্যার জন্য আরও কঠোরভাবে উপযুক্ত? এই সমস্যাগুলি কি কেবল আমি প্রোগ্রাম করার চেষ্টা করছি তার অন্তর্নিহিত জটিলতার কারণে উদ্ভূত হয়েছিল; অর্থাত্ এফআরপিতে কি একই রকম সমস্যা থাকবে?