সত্তা উপাদান উপাদান ভিত্তিক ইঞ্জিন


9

দ্রষ্টব্য: আমি এটি জাভাস্ক্রিপ্টে প্রোগ্রামিং করছি তবে এটি বেশিরভাগ অংশে ভাষা অজ্ঞাবলিক হওয়া উচিত।

আমি আমার ইঞ্জিনটিকে ইসিএস ভিত্তিক একটিতে রূপান্তর করার বিষয়ে ভাবছি।

আমি মূল ধারণাটি পেয়েছি ( দ্রষ্টব্য: এটি ভুল, আমার উত্তর দেখুন ):

সত্তা গেম অবজেক্টস।
উপাদানগুলি কার্যকারিতার বিট ( reactToInput()) বা রাষ্ট্র ( position) যা সত্তাগুলিতে "আঠালো" পেতে পারে।
সিস্টেমগুলিতে তারা পরিচালনা এবং আপডেট করে এমন সত্ত্বার একটি তালিকা রয়েছে।

তবে, আমি বাস্তবায়ন এবং কিছু বিবরণ পেয়েছি তা সম্পর্কে আমি নিশ্চিত নই ...

প্রশ্ন: একটি সিস্টেম বিভিন্ন ধরণের সত্ত্বায় কাজ করতে পারে? আমি সাধারণত Sceneআমার ইঞ্জিনে ডাকা ক্লাসের উদাহরণ দিয়ে থাকি এবং এটি এখন এই উদ্দেশ্যেও কাজ করবে। একটি দৃশ্য হ'ল সমস্ত বস্তুর একটি ধারক যা রেন্ডার, আপডেট, রেন্ডারিং (লাইট) প্রভাবিত করতে পারে এবং ভবিষ্যতে এমনকি এমনকি 2DSoundEmitterঅবজেক্টগুলিতেও হতে পারে। এটিতে একটি উচ্চ-স্তরের ইন্টারফেস রয়েছে যাতে ব্যবহারকারীর নিজের scene.add()যে আইটেমটি করছেন সে ধরণের এবং সেই ধরণের সমস্ত স্টাফ নিয়ে চিন্তা করার দরকার নেই ।

আমি বুঝতে পারি যে Sceneএকটি সিস্টেম হতে পারে। এটি সত্তা গ্রহণ করে, এগুলিকে সঞ্চয় করে এবং তারপরে এটি তাদের আপডেট পদ্ধতিগুলি কল করতে পারে এবং এমনকি কিছু স্টেট পরিবর্তনও করতে পারে। তবে, একটি সমস্যা রয়েছে: আমি উপরে বর্ণিত হিসাবে, বিভিন্ন ধরণের বস্তু Sceneখাওয়ানো যেতে পারে ! আমার কী করা উচিত, বলুন, এমন একটি দৃশ্যে যেখানে কোনও দৃশ্যে দুটি রেন্ডারযোগ্য অবজেক্ট ("অঙ্কনযোগ্য") থাকে এবং এতে আলোক থাকে? আমি কি ইন্টারঅ্যাক্ট করার আগে এটিকে টাইপ-চেক সত্তা তৈরি করা উচিত? বা, আমি কি এটি আরও নিম্ন স্তরে সমাধান করতে পারি: একটি উপাদান তৈরি করুন যা কোনও বস্তুতে যুক্ত হতে পারে , এবং আলোটি কেবল উপাদান এবং উপাদানগুলির সাথে একটি সত্তা হবে । এটা কি গ্রহণযোগ্য?LightSourceLightSourcePosition

এছাড়াও, এখনও প্রচলিত উত্তরাধিকার এবং traditionalতিহ্যবাহী ক্লাস ব্যবহার করা কি একটি ভাল অনুশীলন? উদাহরণস্বরূপ, আমার কী হবে তা আমি ঠিক বুঝতে পারি না Renderer! এটি কোনও সিস্টেম নয়, কারণ এর একমাত্র কাজটি একটি ক্যামেরা এবং একটি দৃশ্য গ্রহণ করা, সমস্ত কিছু রেন্ডার করা এবং প্রভাবগুলি (যেমন ছায়া) প্রয়োগ করা। এটি প্রসঙ্গে, গেমটির প্রস্থ এবং উচ্চতাও পরিচালনা করে, অনুবাদ করে ... তবে এটি এখনও কোনও সিস্টেম নয়!

সম্পাদনা: আপনি সম্ভবত ইসিএসে পাওয়া কোনও সংস্থানকে সংযুক্ত করতে পারেন? ভাল জিনিস খুঁজে পেতে আমার সমস্যা হচ্ছে।


2
এই পৃষ্ঠায় উত্তরটি পুনরায় পোস্ট করার পরিবর্তে, আমি কেবল এই লিঙ্কটি দেব: গেমদেব.স্ট্যাকেক্সচেঞ্জ / সেকশনস / 23533/… সত্তা থেকে প্রাপ্ত হওয়া উচিত নয়, উপাদানগুলির মধ্যে কোনও পার্থক্য উপাদানগুলির মাধ্যমে সম্পন্ন করা উচিত। সাধারণত প্রতিটি বড় সিস্টেমের জন্য আপনার ইন্টারফেসের প্রয়োজন হবে (রেন্ডারিং, ফিজিক্স, নেটওয়ার্কিং, ইনপুট, অডিও, ইত্যাদি ...)। আমি আমার রেন্ডারারকে যেভাবে সেটআপ করেছি তা হল রেন্ডারযোগ্য সত্তাগুলির জন্য দৃশ্যটি অনুসন্ধান করা, এবং দৃশ্যের পরিচালক তার প্রত্যেকটি সত্তাকে জিজ্ঞাসা করার চেয়ে তার রেন্ডারযুক্ত তথ্যের জন্য এতে রেন্ডার উপাদান রয়েছে।
নিক ফস্টার

1
টি = মেশিন ব্লগে কম্পোনেন্ট ডিজাইন (যেহেতু আপনি একটি ভাল চেয়েছিলেন)
জন ম্যাকডোনাল্ড

কোনও সত্তা কাঠামোর কোড এবং আলোচনা: gamadu.com/artemis
প্যাট্রিক হিউজ

@ জনম্যাকডোনাল্ড, আমি সেই নিবন্ধটি সম্পর্কে একটি মন্তব্য লিখেছিলাম, যদিও এটি সংযমের অপেক্ষায় রয়েছে। আপনি এটি এখানে দেখতে পাবেন: t-machine.org/index.php/2007/12/22/… । আমি "ইন্নবনে"।
jcora

এছাড়াও, @ নিকফোস্টার, জন টি-মেশিনে লিঙ্কটি যে লিঙ্কটির সাথে সংযুক্ত করেছেন তাতে আপনার উত্তরের চেয়ে আলাদা কিছু বর্ণনা করা হয়েছে ... সেই ডেভের কাছে সত্তা উপাদানগুলির একটি তালিকা নেই, সেগুলি কেবল একটি নাম। "Flsjn304" - এর মতো এটি একটি সত্তা। এটি "কোথাও" সংরক্ষণ করা হয়। এবং তিনি বুঝতে চাইলে আমাকে পুনরায় পড়তে হবে যদি সে আসলে সিস্টেমগুলির অভ্যন্তরে উপাদান রাখে , যা আমার কাছে খুব অদ্ভুত বলে মনে হচ্ছে !
jcora

উত্তর:


6

ওয়েব / ইউআই জেএস দেব হিসাবে বোঝার চেষ্টা করে যদি আমি দেখতে পাই তবে আমি সাহায্য করতে পারি। এছাড়াও, ভাষা অজ্ঞাতবাদে খুব বেশি দূরে যাবেন না। অন্যান্য ভাষায় প্রতিষ্ঠিত প্রচুর নিদর্শনগুলি অধ্যয়নের জন্য উপযুক্ত তবে এটির নমনীয়তার কারণে জেএসে খুব আলাদাভাবে প্রয়োগ করা যেতে পারে বা ভাষার ক্ষতিকারক প্রকৃতির কারণে সত্যই প্রয়োজন হয় না। আপনি যদি জেএস সম্পর্কে আপনার কোড চিন্তাভাবনাটি একই ধরণের সীমানার সমাহার করে যা আরও ক্লাসিকাল ওওপি-ভিত্তিক ভাষা করে তবে আপনি লিখতে পারেন কিছু সুযোগ blow

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

উত্তরাধিকার ভারী পন্থাগুলি আসলে নকশার প্যাটার্নগুলিতে অ্যান্টি-প্যাটার্ন হিসাবে বানানো হয় এবং সঙ্গত কারণেই যে 15+ স্তরের শ্রেণি বা শ্রেণীর মতো কাঠামোকে অনুসরণ করে দেখেছিল এবং হ্যাকটি কোনও পদ্ধতির ফাঁসানো সংস্করণটি কোথায় তা খুঁজে বের করতে পারে থেকে আসা ছিল আপনি বলতে পারেন।

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

জেএস ডেভ সত্তা / উপাদান / সিস্টেম ভিত্তিক ইঞ্জিনগুলি আমাকে ডিজাইন উদ্বেগগুলি ডিউপল করার জন্য সিস্টেম / প্যাটার্ন হিসাবে আঘাত করে এবং তারপরে উচ্চতর দানাদার স্তরে বাস্তবায়নের জন্য অবজেক্টগুলি সংমিশ্রণ করে। অন্য কথায়, জাভাস্ক্রিপ্টের মতো ভাষায় বাচ্চার খেলা। তবে আমাকে দেখতে দিন আমি প্রথমে এটি সঠিকভাবে ছাঁটাই করছি কিনা।

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

  • উপাদান - একটি সত্তা প্রয়োজনীয় জিনিসগুলির ধরণের। এগুলি হ'ল সাধারণ বিশেষ্য। ওয়াকিংএনিমেশনের মতো। ওয়াকিংএনিমেশনের মধ্যে আমরা আরও নির্দিষ্টভাবে পেতে পারি, যেমন "শ্যাম্বলিং" (জম্বি এবং উদ্ভিদ দানবদের জন্য ভাল পছন্দ), বা "চিকেনওয়ালার" (বিপরীত-যৌথ এড -209ish রোবোট-প্রকারের জন্য দুর্দান্ত)। দ্রষ্টব্য: নিশ্চিত যে এটি কীভাবে 3 ডি মডেলের উপস্থাপনা থেকে দ্বিগুণ হতে পারে - তাই সম্ভবত একটি বোকা উদাহরণ তবে আমি অভিজ্ঞ গেম ডেভের চেয়ে জেএস প্রো বেশি। জেএসে আমি উপাদানগুলির সাথে একই বাক্সে ম্যাপিংয়ের ব্যবস্থা রাখব। তাদের নিজস্ব অংশের উপাদানগুলি যুক্তিবাদে হালকা হতে পারে এবং একটি রোডম্যাপ আপনার সিস্টেমগুলিকে জানায় যে সিস্টেমগুলি এমনকি প্রয়োজন হলে কী প্রয়োগ করতে হবে (ইসিএসে আমার প্রচেষ্টায় কিছু উপাদান কেবল সম্পত্তির সেট সংগ্রহ)। একবার উপাদান তৈরি হয়ে গেলে, এটি '

  • সিস্টেম - আসল প্রোগ্রামমি মাংস এখানে। এআই সিস্টেমগুলি নির্মিত এবং সংযুক্ত, রেন্ডারিং অর্জিত হয়, অ্যানিমেশন সিকোয়েন্সগুলি প্রতিষ্ঠিত হয় ইত্যাদি ... আমি কপি করছি এবং এগুলি বেশিরভাগ কল্পনাতে রেখে দিচ্ছি তবে উদাহরণস্বরূপ সিস্টেম.এআইআই একগুচ্ছ বৈশিষ্ট্য গ্রহণ করে এবং একটি ফাংশন স্পিট করে যা অবশেষে বাস্তবায়নে ব্যবহৃত হয় এমন বস্তুটিতে ইভেন্ট হ্যান্ডলার যুক্ত করতে ব্যবহৃত হয়। সিস্টেম.এআইএর মূল বিষয়টি হ'ল এটি একাধিক উপাদান ধরণের। আপনি একটি উপাদান দিয়ে সমস্ত এআই জিনিসগুলি বাছাই করতে পারেন তবে এটি করার জন্য জিনিসগুলিকে দানাদার তৈরি করার বিষয়টিকে ভুল বোঝা উচিত।

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

তাই জেএসে, সম্ভবত এরকম কিছু। গেম ডেভস দয়া করে আমাকে বলুন আমি এটি ভয়াবহভাবে ভুল পেয়েছি কিনা:

//I'm going with simple objects of flags over arrays of component names
//easier to read and can provide an opt-out default
//Assume a genre-bending stealth assassin game

//new (function etc... is a lazy way to define a constructor and auto-instantiate
var npcEntities = new (function NpcEntities(){

    //note: {} in JS is an object literal, a simple obj namespace (a dictionary)
    //plain ol' internal var in JS is akin to a private member
    var default={ //most NPCs are humanoids and critters - why repeat things?
        speedAttributes:true,
        maneuverAttributes:true,
        combatAttributes:true,
        walkingAnimation:true,
        runningAnimation:true,
        combatAnimation:true,
        aiOblivious:true,
        aiAggro:true,
        aiWary:true, //"I heard something!"
        aiFearful:true
    };

    //this. exposes as public

    this.zombie={ //zombies are slow, but keep on coming so don't need these
        runningAnimation:false,
        aiFearful:false
    };

    this.laserTurret={ //most defaults are pointless so ignore 'em
        ignoreDefault:true,
        combatAttributes:true,
        maneuverAttrubtes:true, //turning speed only
    };
    //also this.nerd, this.lawyer and on and on...

    //loop runs on instantiation which we're forcing on the spot

    //note: it would be silly to repeat this loop in other entity collections
    //but I'm spelling it out to keep things straight-forward.
    //Probably a good example of a place where one-level inheritance from
    //a more general entity class might make sense with hurting the pattern.
    //In JS, of course, that would be completely unnecessary. I'd just build a
    //constructor factory with a looping function new objects could access via
    //closure.

    for(var x in npcEntities){

        var thisEntity = npcEntities[x];

        if(!thisEntity.ignoreDefaults){

            thisEntity = someObjectXCopyFunction(defaults,thisEntity);
            //copies entity properties over defaults

        }
        else {
            //remove nonComponent property since we loop again later
            delete thisEntity.ignoreDefaults;
        }
    }
})() //end of entity instantiation

var npcComponents = {
    //all components should have public entityMap properties

    //No systems in use here. Just bundles of related attributes
    speedAttributes: new (function SpeedAttributes(){
        var shamblingBiped = {
            walkingAcceleration:1,
            topWalking:3
        },
        averageMan = {
            walkingAcceleration:3,
            runningAcceleration:4,
            topWalking: 4,
            topRunning: 6
        },
        programmer = {
            walkingAcceleration:1,
            runningAcceleration:100,
            topWalking:2
            topRunning:2000
        }; //end local/private vars

        //left is entity names | right is the component subcategory
        this.entityMap={
            zombie:shamblingBiped,
            lawyer:averageMan,
            nerd:programmer,
            gCostanza:programmer //makes a cameo during the fire-in-nursery stage
        }
    })(), //end speedAttributes

    //Now an example of an AI component - maps to function used to set eventHandlers
    //functions which, because JS is awesome we can pass around like candy
    //I'll just use some imaginary systems on this one

    aiFearful: new (function AiFearful(){
        var averageMan = Systems.AI({ //builds and returns eventSetting function
            fearThreshold:70, //%hitpoints remaining
            fleeFrom:'lastAttacker',
            tactic:'avoidIntercept',
            hazardAwareness:'distracted'
        }),
        programmer = Systems.AI({
            fearThreshold:95,
            fleeFrom:'anythingMoving',
            tactic:'beeline',
            hazardAwareness:'pantsCrappingPanic'
        });//end local vars/private members


         this.entityMap={
            lawyer:averageMan,
            nerd:averageMan, //nerds can run like programmers but are less cowardly
            gCostanza:programmer //makes a cameo during the fire-in-nursery stage
        }
    })(),//and more components...

    //Systems.AI is general and would get called for all the AI components.
    //It basically spits out functions used to set events on NPC objects that
    //determine their behavior. You could do it all in one shot but
    //the idea is to keep it granular enough for designers to actually tweak stuff
    //easily without tugging on developer pantlegs constantly.
    //e.g. SuperZombies, zombies, but slightly tougher, faster, smarter
}//end npcComponents

function createNPCConstructor(npcType){

    var components = npcEntities[npcType],

    //objConstructor is returned but components is still accessible via closure.

    objConstructor = function(){
        for(var x in components){
            //object iteration <property> in <object>

            var thisComponent = components[x];

            if(typeof thisComponent === 'function'){
                thisComponent.apply(this);
                //fires function as if it were a property of instance
                //would allow the function to add additional properties and set
                //event handlers via the 'this' keyword
            }
            else {
                objConstructor.prototype[x] = thisComponent;
                //public property accessed via reference to constructor prototype
                //good for low memory footprint among other things
            }
        }
    }
    return objConstructor;
}

var npcBuilders= {}; //empty object literal
for (var x in npcEntities){
    npcConstructors[x] = createNPCConstructor(x);
}

এখন যে কোনও সময় আপনার এনপিসি প্রয়োজন, আপনি এটি তৈরি করতে পারেন npcBuilders.<npcName>();

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


এই ছয় বছর পরে এ খুঁজছেন, আমি আমার নিজের উত্তর বুঝতে নিশ্চিত না। এই উন্নতি করা যেতে পারে?
এরিক রেপেন

1

আমি প্রবন্ধগুলিতে এন্টি সিস্টেমগুলিতে পড়েছি যা दयालु লোকেরা মন্তব্যগুলিতে সরবরাহ করেছিল তবে আমার এখনও কিছুটা সন্দেহ ছিল, তাই আমি আরও একটি প্রশ্ন জিজ্ঞাসা করেছি ।

প্রথমত, আমার সংজ্ঞাগুলি ভুল ছিল। সত্তা এবং উপাদানগুলি কেবল বোবা ডেটা ধারক, অন্যদিকে সিস্টেমগুলি সমস্ত কার্যকারিতা সরবরাহ করে।

আমি আমার বেশিরভাগ প্রশ্নের এখানে কভার করার জন্য যথেষ্ট শিখেছি, তাই আমি এটির উত্তর দেব।

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

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

দ্য Rendererকেবল একটি সিস্টেম হিসাবে প্রয়োগ করা যেতে পারে। এটি draw()আঁকতে সক্ষম অবজেক্টের একটি তালিকা বজায় রাখে এবং প্রতি 16 মিনিটে তাদের রেন্ডার উপাদানটির পদ্ধতিতে কল করে ।


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

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

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

1
ছায়া ingালাই স্বাভাবিকভাবে আলোর উত্সগুলির সাথে সংযুক্ত থাকে, যদিও আপনি কেবল "ক্যাসটশ্যাডো" উপাদান তৈরি করতে পারেন এবং গতিশীল অবজেক্টগুলি রেন্ডার করার জন্য এটি সন্ধান করতে পারেন। যদি আপনি 2 ডি করছেন তবে এটি কেবল অর্ডার দেওয়ার একটি প্রাথমিক সমস্যা, একটি সাধারণ চিত্রশিল্পীর অ্যালগরিদম আপনার জন্য এই সমস্যাটি সমাধান করবে। টিবিএইচ আপনি খুব তাড়াতাড়ি দুশ্চিন্তা করছেন। এটি করার সময় হয়ে গেলে আপনি এটি আবিষ্কার করতে পারবেন এবং আপনার মনে কেবল এটি আছে, এখনই আপনি কেবল নিজেকে বিভ্রান্ত করছেন। আপনি প্রথমবার সবকিছু ঠিকঠাক পাওয়ার আশা করতে পারবেন না, এটি ঠিক হবে না। আপনি যখন সেতুটি পৌঁছে যাবেন তখন আপনি পার হবেন।
dreta

1
"সত্ত্বা এবং উপাদানগুলি কেবল বোবা ডেটা ধারক, যখন সিস্টেমগুলি সমস্ত কার্যকারিতা সরবরাহ করে।" অগত্যা। তারা কিছু লোকের মধ্যে রয়েছে in তবে অন্যরা নয়। ইউনিটির ইঞ্জিনটি দেখুন - সমস্ত আচরণ উপাদানগুলির মধ্যে রয়েছে।
কাইলোটন

-2

নির্ভরতা পরিচালনার পরিচিতি 101।

এই কোর্সটি ধরে নিল আপনার নির্ভরতা ইনজেকশন এবং সংগ্রহশালা নকশার প্রাথমিক জ্ঞান রয়েছে।

নির্ভরতা ইনজেকশন হ'ল অবজেক্টের একে অপরের সাথে কথা বলা (ম্যাসেজ / সিগন্যাল / প্রতিনিধি / যাই হোক না কেন) সরাসরি যুক্ত না হয়ে কথা বলা।

এটি বাক্যাংশ দ্বারা যায়: "new আঠালো।"

আমি এটি সি # তে প্রদর্শন করব।

public interface IEntity
{
    int[] Position { get; }
    int[] Size { get; }
    bool Update();
    void Render();
}

public interface IRenderSystem
{
    void Draw(IEntity entity);
}

public interface IMovementSystem
{
    bool CanMoveLeft();
    void MoveLeft();
    bool CanMoveRight();
    void MoveRight();
    bool CanMoveUp();
    void MoveUp();
    bool CanMoveDown();
    void MoveDown();
    bool Moved();
    int[] Position { get; set; }
}

public interface IInputSystem
{
    string Direction { get; set; }
}

public class Player : IEntity
{
    private readonly IInputSystem _inputSystem;
    private readonly IMovementSystem _movementSystem;
    private readonly IRenderSystem _renderSystem;
    private readonly int[] _size = new[] { 10, 10 };

    public Player(IRenderSystem renderSystem, IMovementSystem movementSystem, IInputSystem inputSystem)
    {
        _renderSystem = renderSystem;
        _movementSystem = movementSystem;
        _inputSystem = inputSystem;
    }

    public bool Update()
    {
        if (_inputSystem.Direction == "Left" && _movementSystem.CanMoveLeft())
            _movementSystem.MoveLeft();
        if (_inputSystem.Direction == "Right" && _movementSystem.CanMoveRight())
            _movementSystem.MoveRight();
        if (_inputSystem.Direction == "Up" && _movementSystem.CanMoveUp())
            _movementSystem.MoveUp();
        if (_inputSystem.Direction == "Down" && _movementSystem.CanMoveDown())
            _movementSystem.MoveDown();

        return _movementSystem.Moved();
    }

    public void Render()
    {
        if (_movementSystem.Moved())
            _renderSystem.Draw(this);
    }

    public int[] Position
    {
        get { return _movementSystem.Position; }
    }

    public int[] Size
    {
        get { return _size; }
    }
}

এটি ইনপুট, চলন এবং রেন্ডারিংয়ের জন্য একটি প্রাথমিক সিস্টেম is Playerবর্গ এই ক্ষেত্রে সত্তা নেই এবং উপাদান ইন্টারফেস আছে। Playerবর্গ কিভাবে একটি কংক্রিট internals সম্পর্কে কিছুই জানে না IRenderSystem, IMovementSystemঅথবা IInputSystemহবে। তবে ইন্টারফেসগুলি এর জন্য একটি উপায় সরবরাহ করেPlayer শেষ ফলাফলটি কীভাবে সম্পন্ন হয় তার উপর নির্ভর করে সিগন্যালগুলি প্রেরণের জন্য (যেমন আইআরেন্ডার সিস্টেমে অঙ্কন করতে চান) ।

উদাহরণস্বরূপ, আমার আইভোভমেন্ট সিস্টেমটি প্রয়োগ করুন:

public interface IGameMap
{
    string LeftOf(int[] currentPosition);
    string RightOf(int[] currentPosition);
    string UpOf(int[] currentPosition);
    string DownOf(int[] currentPosition);
}

public class MovementSystem : IMovementSystem
{
    private readonly IGameMap _gameMap;
    private int[] _previousPosition;
    private readonly int[] _currentPosition;
    public MovementSystem(IGameMap gameMap, int[] initialPosition)
    {
        _gameMap = gameMap;
        _currentPosition = initialPosition;
        _previousPosition = initialPosition;
    }

    public bool CanMoveLeft()
    {
        return _gameMap.LeftOf(_currentPosition) == "Unoccupied";
    }

    public void MoveLeft()
    {
        _previousPosition = _currentPosition;
        _currentPosition[0]--;
    }

    public bool CanMoveRight()
    {
        return _gameMap.RightOf(_currentPosition) == "Unoccupied";
    }

    public void MoveRight()
    {
        _previousPosition = _currentPosition;
        _currentPosition[0]++;
    }

    public bool CanMoveUp()
    {
        return _gameMap.UpOf(_currentPosition) == "Unoccupied";
    }

    public void MoveUp()
    {
        _previousPosition = _currentPosition;
        _currentPosition[1]--;
    }

    public bool CanMoveDown()
    {
        return _gameMap.DownOf(_currentPosition) == "Unoccupied";
    }

    public void MoveDown()
    {
        _previousPosition = _currentPosition;
        _currentPosition[1]++;
    }

    public bool Moved()
    {
        return _previousPosition == _currentPosition;
    }

    public int[] Position
    {
        get { return _currentPosition; }
    }
}

MovementSystemএর নিজস্ব নির্ভরতা থাকতে পারে এবং Playerএমনকি যত্নও করতে পারে না। ইন্টারফেস ব্যবহার করে, একটি গেম স্টেট মেশিন তৈরি করা যেতে পারে:

public class GameEngine
{
    private readonly List<IEntity> _entities;
    private List<IEntity> _renderQueue; 

    public GameEngine()
    {
        _entities = new List<IEntity>();
    }

    public void RegisterEntity(IEntity entity)
    {
        _entities.Add(entity);
    }

    public void Update()
    {
        _renderQueue = new List<IEntity>();
        foreach (var entity in _entities)
        {
            if(entity.Update())
                _renderQueue.Add(entity);
        }
        // Linq version for those interested
        //_renderQueue.AddRange(_entities.Where(e => e.Update()));
    }

    public void Render()
    {
        foreach (var entity in _renderQueue)
        {
            entity.Render();
        }
    }
}

এবং এটি একটি সুন্দর খেলা শুরু (এটিও ইউনিট পরীক্ষামূলক) able

এবং কয়েকটি সংযোজন এবং কিছু পলিমারফিজম সহ:

public interface IEntity
{
}

public interface IRenderableEntity : IEntity
{
    void Render();        
}

public interface IUpdateableEntity : IEntity
{
    void Update();
    bool Updated { get; }
}

public interface IRenderSystem
{
    void Draw(IRenderableEntity entity);
}

// new player class
public class Player : IRenderableEntity, IUpdateableEntity
{
    private readonly IInputSystem _inputSystem;
    private readonly IMovementSystem _movementSystem;
    private readonly IRenderSystem _renderSystem;
    private readonly int[] _size = new[] { 10, 10 };

    public Player(IRenderSystem renderSystem, IMovementSystem movementSystem, IInputSystem inputSystem)
    {
        _renderSystem = renderSystem;
        _movementSystem = movementSystem;
        _inputSystem = inputSystem;
    }

    public void Update()
    {
        if (_inputSystem.Direction == "Left" && _movementSystem.CanMoveLeft())
            _movementSystem.MoveLeft();
        if (_inputSystem.Direction == "Right" && _movementSystem.CanMoveRight())
            _movementSystem.MoveRight();
        if (_inputSystem.Direction == "Up" && _movementSystem.CanMoveUp())
            _movementSystem.MoveUp();
        if (_inputSystem.Direction == "Down" && _movementSystem.CanMoveDown())
            _movementSystem.MoveDown();
    }

    public bool Updated
    {
        get { return _movementSystem.Moved(); }
    }

    public void Render()
    {
        if (_movementSystem.Moved())
            _renderSystem.Draw(this);
    }

    public int[] Position
    {
        get { return _movementSystem.Position; }
    }

    public int[] Size
    {
        get { return _size; }
    }
}

public class GameEngine
{
    private readonly List<IEntity> _entities;
    private List<IRenderableEntity> _renderQueue; 

    public GameEngine()
    {
        _entities = new List<IEntity>();
    }

    public void RegisterEntity(IEntity entity)
    {
        _entities.Add(entity);
    }

    public void Update()
    {
        _renderQueue = new List<IRenderableEntity>();
        foreach (var entity in _entities)
        {
            if (entity is IUpdateableEntity)
            {
                var updateEntity = entity as IUpdateableEntity;
                updateEntity.Update();
            }

            if (entity is IRenderableEntity)
            {
                var renderEntity = entity as IRenderableEntity;
                _renderQueue.Add(renderEntity);
            }
        }
    }

    public void Render()
    {
        foreach (var entity in _renderQueue)
        {
            entity.Render();
        }
    }
}

আমাদের এখন একত্রিত ইন্টারফেস এবং আলগা উত্তরাধিকারের ভিত্তিতে একটি আদিম সত্তা / উপাদান সিস্টেম রয়েছে।


1
এটি উপাদান ডিজাইনের বিপরীতে :) আপনি যদি একজন প্লেয়ারকে শব্দ করতে চান এবং অন্যটি না করেন তবে আপনি কী করবেন?
কিকাইমারু

@ কাইকমারু পাসওয়ার্ড করুন এমন একটি ইসাউন্ডসিস্টেম যা শব্দ বাজায় না। অর্থাত্ কিছুই করে না।
ডাস্টিন কিনেঞ্জ

3
-1, এটি খারাপ কোড নয় বলে নয়, কারণ এটি উপাদান-ভিত্তিক আর্কিটেকচারের সাথে মোটেই প্রাসঙ্গিক নয় - বাস্তবে এটি এই জাতীয় ইন্টারফেসের বিস্তার যা উপাদানগুলি এড়াতে চেষ্টা করে।
কাইলোটন

@ কাইলোটান আমার ধারণা আমার বুঝতে ভুল হতে হবে।
ডাস্টিন কিনেঞ্জ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.