এএবিবি সংঘর্ষের সাথে প্ল্যাটফর্মের জাম্পিং সমস্যা


9

প্রথমে চিত্রটি দেখুন:

আমার এএবিবি পদার্থবিজ্ঞানের ইঞ্জিন যখন কোনও ছেদটি সমাধান করে, অনুপ্রবেশ ছোট যেখানে অক্ষটি সন্ধান করে এটি করা হয়, তারপরে সেই অক্ষের সত্তাকে "ধাক্কা দিয়ে" ফেলে।

"জাম্পিং মুভিং বাম" উদাহরণ বিবেচনা করে:

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

কিভাবে আমি এই সমস্যার সমাধান করতে পারে?

সোর্স কোড:

public void Update()
{
    Position += Velocity;
    Velocity += World.Gravity;

    List<SSSPBody> toCheck = World.SpatialHash.GetNearbyItems(this);

    for (int i = 0; i < toCheck.Count; i++)
    {
        SSSPBody body = toCheck[i];
        body.Test.Color = Color.White;

        if (body != this && body.Static)
        {                   
            float left = (body.CornerMin.X - CornerMax.X);
            float right = (body.CornerMax.X - CornerMin.X);
            float top = (body.CornerMin.Y - CornerMax.Y);
            float bottom = (body.CornerMax.Y - CornerMin.Y);

            if (SSSPUtils.AABBIsOverlapping(this, body))
            {
                body.Test.Color = Color.Yellow;

                Vector2 overlapVector = SSSPUtils.AABBGetOverlapVector(left, right, top, bottom);

                Position += overlapVector;
            }

            if (SSSPUtils.AABBIsCollidingTop(this, body))
            {                      
                if ((Position.X >= body.CornerMin.X && Position.X <= body.CornerMax.X) &&
                    (Position.Y + Height/2f == body.Position.Y - body.Height/2f))
                {
                    body.Test.Color = Color.Red;
                    Velocity = new Vector2(Velocity.X, 0);

                }
            }
        }               
    }
}

public static bool AABBIsOverlapping(SSSPBody mBody1, SSSPBody mBody2)
{
    if(mBody1.CornerMax.X <= mBody2.CornerMin.X || mBody1.CornerMin.X >= mBody2.CornerMax.X)
        return false;
    if (mBody1.CornerMax.Y <= mBody2.CornerMin.Y || mBody1.CornerMin.Y >= mBody2.CornerMax.Y)
        return false;

    return true;
}
public static bool AABBIsColliding(SSSPBody mBody1, SSSPBody mBody2)
{
    if (mBody1.CornerMax.X < mBody2.CornerMin.X || mBody1.CornerMin.X > mBody2.CornerMax.X)
        return false;
    if (mBody1.CornerMax.Y < mBody2.CornerMin.Y || mBody1.CornerMin.Y > mBody2.CornerMax.Y)
        return false;

    return true;
}
public static bool AABBIsCollidingTop(SSSPBody mBody1, SSSPBody mBody2)
{
    if (mBody1.CornerMax.X < mBody2.CornerMin.X || mBody1.CornerMin.X > mBody2.CornerMax.X)
        return false;
    if (mBody1.CornerMax.Y < mBody2.CornerMin.Y || mBody1.CornerMin.Y > mBody2.CornerMax.Y)
        return false;

    if(mBody1.CornerMax.Y == mBody2.CornerMin.Y)
        return true;

    return false;
}
public static Vector2 AABBGetOverlapVector(float mLeft, float mRight, float mTop, float mBottom)
{
    Vector2 result = new Vector2(0, 0);

    if ((mLeft > 0 || mRight < 0) || (mTop > 0 || mBottom < 0))
        return result;

    if (Math.Abs(mLeft) < mRight)
        result.X = mLeft;
    else
        result.X = mRight;

    if (Math.Abs(mTop) < mBottom)
        result.Y = mTop;
    else
        result.Y = mBottom;

    if (Math.Abs(result.X) < Math.Abs(result.Y))
        result.Y = 0;
    else
        result.X = 0;

    return result;
}

উত্তর:


2
  • আপনি যদি ইতিমধ্যে এটি না করে থাকেন তবে আপনার সমস্ত সমর্থনকারী ফাংশন (দ্বিতীয় কোড তালিকায়) পরীক্ষা করুন।
  • এই বস্তুটি কী করে তা স্ট্যান্ডার্ড আউটপুটে ভিজ্যুয়ালাইজ করুন বা মুদ্রণ করুন। নিশ্চিত হয়ে নিন যে প্রতিটি কোড কী করে এবং এটি এটি পুরোপুরি কার্যকর করে তা আপনি জানেন know
  • সংঘর্ষের মধ্যে অনেকগুলি অন্তর্দৃষ্টি রয়েছে http://www.flipcode.com/archives/Theory_P ੈਕਟ- Issue_01_Collision_Dtetection.shtml

আমি কেবল কোডটি দেখেছি যেখানে প্রমাণ করার চেষ্টা করিনি এটি কোথায় ভুল is

আমি কোডটি দেখলাম এবং এই 2 টি লাইনটি অদ্ভুত বলে মনে হয়েছিল:

if ((Position.X >= body.CornerMin.X && Position.X <= body.CornerMax.X) &&
(Position.Y + Height/2f == body.Position.Y - body.Height/2f))

আপনি বিরতি পরীক্ষা করেন এবং তারপরে আপনি ইক্যুয়ালিটির জন্য পরীক্ষা করেন? আমি ভুল হতে পারি, (কিছুটা হলেও চলছে) তবে মনে হচ্ছে এটি কোনও সমস্যার কারণ হতে পারে।


0

অন্যান্য লোকের কোড পড়া খুব কঠিন, তবে আমি মনে করি এটি একমাত্র সম্ভব (বিশুদ্ধ মস্তিষ্কভিত্তিক) কাজ, যদিও অবশ্যই আমি এটি পরীক্ষা করতে পারছি না:

  1. সংঘর্ষ সনাক্তকরণ হওয়ার আগে খেলোয়াড়দের বেগটি কিছু অস্থায়ী পরিবর্তনশীলে সংরক্ষণ করুন able
  2. আপনি নিজের সংঘর্ষের প্রতিক্রিয়াটি সম্পন্ন করার পরে, খেলোয়াড়দের এক্স বা ওয়াই অবস্থান সঠিক হয়েছে কিনা তা পরীক্ষা করে দেখুন
  3. যদি এক্স অবস্থানটি পরিবর্তন করা হয় তবে খেলোয়াড়দের ওয়াই বেগ সাড়া দেওয়ার আগে তার যে খেলোয়াড়ের ওয়াই বেগ ছিল তা ম্যানুয়ালি রিসেট করুন (এক ধরণের "সুরক্ষা পুনঃস্থাপন" হিসাবে)।

যাইহোক, যখন আপনার খেলোয়াড়রা লাফানোর সময় ছাদে আঘাত করে তখন আপনার বর্তমান কোডটির সাথে কী ঘটে?


গতিবেগ পরিবর্তন করা কোনও সমস্যার সমাধান করতে পারে না, কারণ সংঘর্ষের প্রতিক্রিয়ার দ্বারা বেগটি প্রভাবিত হয়নি। প্রতিক্রিয়া কেবল খেলোয়াড়ের অবস্থান পরিবর্তন করে, वेगটি অপরিবর্তিত রেখে। প্লেয়ার যখন ছাদে আঘাত করে তখন এটি কিছুক্ষণের জন্য ভেসে যায় তারপরে ফিরে আসে। এটি সীমাবদ্ধতার দিকে ছড়িয়ে পড়ার পর থেকেই আমি वेगটি 0 তে সেট করছি না বলে এটি উদ্দেশ্য intended
ভিটোরিও রোমিও

আপনি getOverlapVector পদ্ধতিতে ফলাফল ভেক্টর উপাদানগুলির একটিরও শূন্যতে সেট করে এমন কোডটি সরিয়ে ফেললে কী হবে?
ট্র্যাভিসজি

সত্তাটি তির্যকভাবে ঠেলাঠেলি করে, কখনও কখনও এটি সঠিকভাবে কাজ করে না, অন্য সময় এটি কেবল গ্রিডে রাখার মতো স্ন্যাপ দেয়।
ভিটোরিও রোমিও

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