อัลกอริทึมในการยิงที่เป้าหมายในเกม 3 มิติ


11

สำหรับผู้ที่จำ Descent Freespace มันมีคุณสมบัติที่ดีที่จะช่วยให้คุณเล็งไปที่ศัตรูเมื่อยิงขีปนาวุธหรือเลเซอร์ที่ไม่ใช่ homing: มันแสดงเล็งด้านหน้าของเรือรบที่คุณไล่ล่าบอกว่าจะยิงเพื่อเคลื่อนที่ เป้า

ฉันลองใช้คำตอบจาก/programming/4107403/ai-algorithm-to-shoot-at-a-target-in-a-target-in-a-2d-game?lq=1แต่มันเป็นแบบ 2D ดังนั้นฉันจึงลอง ปรับตัว

ฉันแยกย่อยการคำนวณเพื่อแก้จุดตัดสำหรับระนาบ XoZ และบันทึกพิกัด x และ z แล้วแก้จุดตัดสำหรับระนาบ XoY และเพิ่มพิกัด y ไปยัง xyz สุดท้ายที่ฉันเปลี่ยนเป็นพื้นผิวแล้ว พิกัด. แต่แน่นอนว่ามันใช้งานไม่ได้อย่างที่ควรหรืออย่างอื่นฉันจะไม่โพสต์คำถาม

จากสิ่งที่ฉันสังเกตเห็นหลังจากพบ x ในระนาบ XoZ และใน XoY the 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);

ครั้งแรกที่ targetVelocity.y เป็น targetVelocity.z (เหมือนกันสำหรับ targetPos) และครั้งที่สองก็เป็น targetVelocity.y

ตำแหน่งสุดท้ายหลังจาก XoZ คือ

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

และหลังจาก XoY

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

วิธีการของฉันในการแยกออกเป็น 2 ระนาบและคำนวณความดีใด ๆ หรือสำหรับ 3D มีวิธีการที่แตกต่างกันโดยสิ้นเชิง?

  • sqr () เป็นตารางไม่ใช่ sqrt - หลีกเลี่ยงความสับสน

1
"การนำเป้าหมาย" อาจเป็นวลีที่คุณต้องการ
MichaelHouse

คำตอบ:


12

ไม่จำเป็นต้องแบ่งมันออกเป็นฟังก์ชั่น 2 2d สมการกำลังสองที่คุณกำลังทำงานด้วยทำงานได้ดีในแบบ 3 มิติเช่นกัน นี่คือโค้ดหลอกสำหรับ 2d หรือ 3d มันหมายถึงหอคอย (Tower Defense) กำลังยิงโปรเจคไทล์:

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 

'aimSpot' อาจเป็นเวคเตอร์ที่คุณกำลังถาม


คุณเป็นอัจฉริยะและช่วยชีวิตฉันไว้ !! ประณามฉันต้องการ 15 ชื่อเสียงในการ
ถอนเงิน

@SebastianBugiu ฉันทำเพื่อคุณ
AgentFire

@SebastianBugiu ขอบคุณฉันดีใจที่ฉันได้เรียนรู้แนวคิดนี้และดีใจที่มันช่วยคุณได้ คุณสมบัติที่ยอดเยี่ยมอีกอย่างของมันคือคุณไม่จำเป็นต้องยุ่งกับอัลกอริทึมการตรวจจับการชนกันของข้อมูล ไม่จำเป็นต้องเขียนโค้ดซีดี เนื่องจากเส้นทางเป้าหมายและกระสุนปืนสามารถคาดการณ์ได้ผลกระทบจะเกิดขึ้นเมื่อtimeToImpactนับลงไปที่ศูนย์
Steve H

1

นอกจากนี้ยังมีโพสต์บล็อกที่ดีเกี่ยวกับเรื่องเดียวกัน: http://playtechs.blogspot.kr/2007/04/aiming-at-moving-target.html 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.