আমি কীভাবে 2 ডি প্ল্যাটফর্মারটিতে অসম প্রাচীরের উপর একটি চরিত্রকে হাঁটতে পারি?


11

আমি একটি খেলতে সক্ষম চরিত্র রাখতে চাই যিনি কোনও কোণে জৈব পৃষ্ঠে "হাঁটাচলা" করতে পারবেন, পার্শ্ববর্তী পথ এবং উত্সাহ-ডাউন সহ। 90-ডিগ্রি কোণে সোজা রেখার পরিবর্তে স্ল্যাটেড এবং বাঁকা বৈশিষ্ট্যযুক্ত "জৈব" স্তর দ্বারা।

আমি বর্তমানে AS3 এ কাজ করছি (পরিমিত শৌখিন অভিজ্ঞতা) এবং বেসিক মাধ্যাকর্ষণ-ভিত্তিক পদার্থবিজ্ঞানের জন্য নেপ (প্রায় এক নবাগত) ব্যবহার করছি, যার কাছে এই হাঁটার মেকানিকটি একটি সুস্পষ্ট ব্যতিক্রম হবে।

এই ধরণের হাঁটার মেকানিকটি কীভাবে সম্ভবত নেপের সীমাবদ্ধতা ব্যবহার করে করার পদ্ধতিগত উপায় আছে? বা স্তরের পৃষ্ঠের সংক্ষিপ্তসারগুলি অনুসরণ করে স্পষ্টভাবে হাঁটার "পথ" তৈরি করা এবং তাদের হাঁটাচলাচলকে বাধা দেওয়ার জন্য ব্যবহার করা ভাল কি হবে?


স্পষ্ট করার জন্য: আপনি আপনার চরিত্রটিকে আপনার স্তরের দেয়াল এবং ছাদে 'কাঠি' রাখতে সক্ষম করতে চান?
কিউকিউই

এটাই সঠিক.
এরিক এন

উত্তর:


9

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

অন্যান্য ক্লাস এবং পদ্ধতিগুলির বেশিরভাগই নেপ প্যাকেজের অংশ। আমার আমদানি তালিকার প্রাসঙ্গিক অংশটি এখানে:

import flash.events.TimerEvent;
import flash.utils.Timer;

import nape.callbacks.CbEvent;
import nape.callbacks.CbType;
import nape.callbacks.InteractionCallback;
import nape.callbacks.InteractionListener;
import nape.callbacks.InteractionType;
import nape.callbacks.OptionType;
import nape.dynamics.Arbiter;
import nape.dynamics.ArbiterList;
import nape.geom.Geom;
import nape.geom.Vec2;

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

        var opType:OptionType = new OptionType([CbType.ANY_BODY]);
        mass = body.mass;
        // Listen for collision with level, before, during, and after.
        var landDetect:InteractionListener =  new InteractionListener(CbEvent.BEGIN, InteractionType.COLLISION, opType, opType, spiderLand)
        var moveDetect:InteractionListener =  new InteractionListener(CbEvent.ONGOING, InteractionType.COLLISION, opType, opType, spiderMove);
        var toDetect:InteractionListener =  new InteractionListener(CbEvent.END, InteractionType.COLLISION, opType, opType, takeOff);

        Level(this.parent).world.listeners.add(landDetect);
        Level(this.parent).world.listeners.add(moveDetect);
        Level(this.parent).world.listeners.add(toDetect);

        /*
            A reference to the spider's parent level's master timer, which also drives the nape world,
            runs a callback within the spider class every frame.
        */
        Level(this.parent).nTimer.addEventListener(TimerEvent.TIMER, tick);

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

    protected function spiderLand(callBack:InteractionCallback):void {
        tArbiters = callBack.arbiters.copy();
        state.isGrounded = true;
        state.isMidair = false;
        body.gravMass = 0;
        toTimer.stop();
        toTimer.reset();
    }

    protected function spiderMove(callBack:InteractionCallback):void {
        tArbiters = callBack.arbiters.copy();
    }

    protected function takeOff(callBack:InteractionCallback):void {
        tArbiters.clear();
        toTimer.reset();
        toTimer.start();
    }

    protected function takeOffTimer(e:TimerEvent):void {
        state.isGrounded = false;
        state.isMidair = true;
        body.gravMass = mass;
        state.isMoving = false;
    }

পরিশেষে, আমি গণনা করি যে মাকড়সার স্থিতি এবং জ্যামিতির স্তরের সম্পর্কের ভিত্তিতে মাকড়সাতে কী প্রয়োগ করতে বাধ্য করে। আমি বেশিরভাগ মন্তব্য তাদের নিজেদের জন্য বলতে হবে।

    protected function tick(e:TimerEvent):void {
        if(state.isGrounded) {
            switch(tArbiters.length) {
                /*
                    If there are no arbiters (i.e. spider is in midair and toTimer hasn't expired),
                    aim the adhesion force at the nearest point on the level geometry.
                */
                case 0:
                    closestA = Vec2.get();
                    closestB = Vec2.get();
                    Geom.distanceBody(body, lvBody, closestA, closestB);
                    stickForce = closestA.sub(body.position, true);
                    break;
                // For one contact point, aim the adhesion force at that point.
                case 1:
                    stickForce = tArbiters.at(0).collisionArbiter.contacts.at(0).position.sub(body.position, true);
                    break;
                // For multiple contact points, add the vectors to find the average angle.
                default:
                    var taSum:Vec2 = tArbiters.at(0).collisionArbiter.contacts.at(0).position.sub(body.position, true);
                    tArbiters.copy().foreach(function(a:Arbiter):void {
                        if(taSum != a.collisionArbiter.contacts.at(0).position.sub(body.position, true))
                            taSum.addeq(a.collisionArbiter.contacts.at(0).position.sub(body.position, true));
                    });

                    stickForce=taSum.copy();
            }
            // Normalize stickForce's strength.
            stickForce.length = 1000;
            var curForce:Vec2 = new Vec2(stickForce.x, stickForce.y);

            // For graphical purposes, align the body (simulation-based rotation is disabled) with the adhesion force.
            body.rotation = stickForce.angle - Math.PI/2;

            body.applyImpulse(curForce);

            if(state.isMoving) {
                // Gives "movement force" a dummy value since (0,0) causes problems.
                mForce = new Vec2(10,10);
                mForce.length = 1000;

                // Dir is movement direction, a boolean. If true, the spider is moving left with respect to the surface; otherwise right.
                // Using the corrected "down" angle, move perpendicular to that angle
                if(dir) {
                    mForce.angle = correctAngle()+Math.PI/2;
                } else {
                    mForce.angle = correctAngle()-Math.PI/2;
                }
                // Flip the spider's graphic depending on direction.
                texture.scaleX = dir?-1:1;
                // Now apply the movement impulse and decrease speed if it goes over the max.
                body.applyImpulse(mForce);
                if(body.velocity.length > 1000) body.velocity.length = 1000;

            }
        }
    }

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

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

    protected function correctAngle():Number {
        var angle:Number;
        if(tArbiters.length < 2) {
            // If there is only one (or zero) contact point(s), the "corrected" angle doesn't change from stickForce's angle.
            angle = stickForce.angle;
        } else {
            /*
                For more than one contact point, we want to run perpendicular to the "new" down, so we copy all the
                contact point angles into an array...
            */
            var angArr:Array = [];
            tArbiters.copy().foreach(function(a:Arbiter):void {
                var curAng:Number = a.collisionArbiter.contacts.at(0).position.sub(body.position, true).angle;
                if (curAng < 0) curAng += Math.PI*2;
                angArr.push(curAng);
            });
            /*
                ...then we iterate through all those contact points' angles with respect to the spider's COM to figure out
                which one is more clockwise or more counterclockwise, depending, with some restrictions...
                ...Whatever, the correct one.
            */
            angle = angArr[0];
            for(var i:int = 1; i<angArr.length; i++) {
                if(dir) {
                    if(Math.abs(angArr[i]-angle) < Math.PI)
                        angle = Math.max(angle, angArr[i]);
                    else
                        angle = Math.min(angle, angArr[i]);
                }
                else {
                    if(Math.abs(angArr[i]-angle) < Math.PI)
                        angle = Math.min(angle, angArr[i]);
                    else
                        angle = Math.max(angle, angArr[i]);
                }
            }
        }

        return angle;
    }

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


1
ভাল হয়েছে, এখানে ভবিষ্যতের দর্শকদের জন্য বিশদ পোস্ট করার জন্য ধন্যবাদ।
মাইকেলহাউস

8

কোনও "কাঠি" পৃষ্ঠকে কোনও চরিত্রের ছোঁয়ায় পৃষ্ঠের বিপরীত স্বাভাবিক বরাবর একটি শক্তি প্রয়োগ করা যায় কীভাবে? তারা ততক্ষণ পৃষ্ঠের সংস্পর্শে থাকবে এবং যতক্ষণ না এটি সক্রিয় থাকবে ততক্ষণ মাধ্যাকর্ষণকে ওভাররাইড করে। সুতরাং সিলিংটি থেকে লাফ দিয়ে মেঝেতে নামার প্রত্যাশিত প্রভাব থাকবে।

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

এখানে চিত্র বর্ণনা লিখুন

(উপস্থাপিত মাকড়সা সদৃশতা বাইট 56 এর সম্পত্তি)

নীল রেখাগুলি সেই বিন্দুতে পৃষ্ঠের বিপরীত স্বাভাবিক are গ্রিন লাইনটি মাকড়সার জন্য প্রয়োগ করা সমষ্টি শক্তি force লাল বৃত্তটি স্পাইডারটি ব্যবহার করতে স্বাভাবিকের সন্ধান করছে এমন পরিসীমা উপস্থাপন করে।

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

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

মনে রাখবেন যে কোনও মুখ যখন মাকড়সার সীমার মধ্যে না থাকে, তখন স্বাভাবিক গ্র্যাভিটি নেয়।


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

দুঃখিত, আমিও পরিচিত নই। ভূখণ্ড তৈরি করার সময় সম্ভবত নিজেকে রক্ষণাবেক্ষণের জন্য এমন কিছু প্রয়োজন।
মাইকেলহাউস

2
আমি এই ধারণাটি বাস্তবায়ন করতে সক্ষম হয়েছি কারণ আমি নেপের সংঘর্ষের যোগাযোগের পয়েন্টগুলি সনাক্ত করতে পারি এবং যদি সেখানে একের বেশি থাকে তবে এগুলিকে গড় করতে পারি। সমতল বা উত্তল পৃষ্ঠের উপর দিয়ে যাওয়ার জন্য এটি প্রয়োজনীয় বলে মনে হচ্ছে না, তবে এটি আমার বৃহত্তম সমস্যাটি সমাধান করেছে: আমার মাকড়সা যখন একটি তীক্ষ্ণ কোণে মুখোমুখি হয় তখন কী করব। আমার নতুন উত্তরে উল্লিখিত হিসাবে, আমি আমার মাকড়সার গ্রাফিকটি ওরিয়েন্ট করতে সহায়তা করার জন্য এই ধারণাটিতে কোনও প্রকারের চেষ্টা করতে পারি।
এরিক এন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.