একটি 3 ডি গেমের লক্ষ্যবস্তুতে শ্যুটিং করতে অ্যালগরিদম


11

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

আমি উত্তরটি /programming/4107403/ai-algorithm-to-shoot-at-a-target-in-a-2d-game?lq=1 থেকে ব্যবহার করার চেষ্টা করেছি তবে এটি 2D এর জন্য তাই আমি চেষ্টা করেছি এটি অভিযোজিত।

আমি প্রথমে XoZ বিমানের জন্য ছেদ স্থানটি সমাধান করার জন্য গণনাটি দ্রবীভূত করে x এবং z স্থানাঙ্কগুলি সংরক্ষণ করে এবং তারপরে XoY বিমানের জন্য ছেদ স্থানটি সমাধান করে এবং y স্থানাঙ্ককে একটি চূড়ান্ত xyz যুক্ত করেছিলাম যা আমি ক্লিপস্পেসে রূপান্তরিত করেছি এবং সেগুলিতে একটি টেক্সচার রেখেছি স্থানাঙ্ক। তবে অবশ্যই এটি যেমনটি করা উচিত তেমন কাজ করে না অন্যথায় আমি প্রশ্ন পোস্ট করতাম না।

এক্সওজেড প্লেনে x এবং XoY এ x সন্ধান করার পরে যা আমি লক্ষ্য করেছি তা থেকে এক্সটি এক নয় তাই কিছু ভুল হতে হবে।

    float a = ENG_Math.sqr(targetVelocity.x) + ENG_Math.sqr(targetVelocity.y) -
            ENG_Math.sqr(projectileSpeed);
    float b = 2.0f * (targetVelocity.x * targetPos.x + 
            targetVelocity.y * targetPos.y);
    float c = ENG_Math.sqr(targetPos.x) + ENG_Math.sqr(targetPos.y);
    ENG_Math.solveQuadraticEquation(a, b, c, collisionTime);

প্রথমবারের টার্গেটভেলোসিটি.ই আসলে টার্গেটভেলোসিটি.জেড (টার্গেটপোসের জন্য একই) এবং দ্বিতীয়বার এটি আসলে টার্গেটভেলোসিটি.ই।

এক্সওজেডের পরে চূড়ান্ত অবস্থান

    crossPosition.set(minTime * finalEntityVelocity.x + finalTargetPos4D.x, 0.0f, 
                minTime * finalEntityVelocity.z + finalTargetPos4D.z);

এবং XoY পরে

    crossPosition.y = minTime * finalEntityVelocity.y + finalTargetPos4D.y;

আমার 2 টি প্লেনের মধ্যে বিভক্ত হওয়ার এবং কোনও গণনা করার পদ্ধতিটি কী ভাল? বা 3 ডি এর জন্য কি সম্পূর্ণ ভিন্ন পদ্ধতির রয়েছে?

  • sqr () বর্গক্ষেত্র নয় বিকাশ - একটি বিভ্রান্তি এড়ানো।

1
"টার্গেটের শীর্ষস্থানীয় হওয়া" আপনি যে বাক্যটি সন্ধান করছেন তা হতে পারে।
মাইকেলহাউস

উত্তর:


12

এটি 2 2 ডি কার্যক্রমে বিভক্ত করার দরকার নেই। আপনি যে চতুর্ভুজ সমীকরণটি 3 ডি তেও কাজ করে তা নিয়ে কাজ করছেন। 2d বা 3 ডি এর জন্য সিউডো কোডটি এখানে। এটি বোঝায় যে একটি টাওয়ার (টাওয়ার ডিফেন্স) প্রক্ষেপণটির শুটিং করছে:

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second 

'লক্ষ্যস্পট' আপনার সম্পর্কে জিজ্ঞাসা করা ভেক্টর হতে পারে।


আপনি একজন প্রতিভা এবং আমার গাধা সংরক্ষণ করেছেন !!
অভিশাপটি আমার উপরে উঠতে

@ সেবাস্তিয়ান বুগিউ আমি এটি আপনার জন্য করেছিলাম।
এজেন্টফায়ার

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

1

একই বিষয় সম্পর্কে একটি ভাল ব্লগ পোস্ট আছে: http://playtechs.blogspot.kr/2007/04/aiming-at-moving-target.html । এটিতে আরও জটিল নমুনাগুলি রয়েছে যা মাধ্যাকর্ষণ অন্তর্ভুক্ত করে।

লেখক আরও সরলীকরণ করেছেন, যার ফলে আরও কমপ্যাক্ট কোড আসে:

double time_of_impact(double px, double py, double vx, double vy, double s)
{
    double a = s * s - (vx * vx + vy * vy);
    double b = px * vx + py * vy;
    double c = px * px + py * py;

    double d = b*b + a*c;

    double t = 0;
    if (d >= 0)
    {
        t = (b - sqrt(d)) / a;
        if (t < 0) 
        {
            t = (b + sqrt(d)) / a;
            if (t < 0)
                t = 0;
        }
    }

    return t;
}

আপডেট: মূল লেখক কেবলমাত্র বৃহত্তর মূলটিকে বিবেচনা করেছেন। তবে ছোট রুটটি অ-নেতিবাচক হওয়ার ক্ষেত্রে এটির সমাধান আরও ভাল হয় কারণ প্রভাবের সময় কম হয়। আমি কোডটি অনুরূপভাবে আপডেট করেছি।

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