การป้องกันหอคอยแบบ 2 มิติ - กระสุนใส่ศัตรู


14

ฉันกำลังพยายามหาวิธีแก้ปัญหาที่ดีสำหรับกระสุนเพื่อตีศัตรู เกมดังกล่าวเป็นการป้องกันหอคอยแบบ 2 มิติหอคอยควรจะยิงเป็นกระสุนและโจมตีศัตรูที่รับประกัน

ฉันลองวิธีแก้ปัญหานี้ - http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

ลิงค์ที่กล่าวถึงเพื่อลบต้นกำเนิดของกระสุนและศัตรูเช่นกัน (การลบเวกเตอร์) ฉันพยายามที่ แต่กระสุนเพียงแค่ติดตามรอบศัตรู

float diffX = enemy.position.x - position.x;
float diffY = enemy.position.y - position.y;

velocity.x = diffX;
velocity.y = diffY;

position.add(velocity.x * deltaTime, velocity.y * deltaTime);

ฉันคุ้นเคยกับเวกเตอร์ แต่ไม่แน่ใจว่าต้องดำเนินการขั้นตอนใด (การดำเนินการคณิตศาสตร์เวกเตอร์) เพื่อให้โซลูชันนี้ทำงานได้


ที่เกี่ยวข้อง: gamedev.stackexchange.com/questions/1885/…
bummzack

คำตอบ:


11

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

Velocity เป็นเวกเตอร์: ความเร็วและทิศทาง แต่ถ้าคุณลืมที่จะปรับเวกเตอร์ที่แตกต่างกันและคูณความเร็วกระสุน (เกลา), คุณมีพื้นบอกว่าถ้าคุณมีความใกล้เคียงกับเป้าหมาย (เวกเตอร์ที่แตกต่างกันมีขนาดเล็ก) ช้ากระสุนลง ; ในขณะที่ถ้าคุณอยู่ไกลความเร็วกระสุนจะยิ่งใหญ่

นี่คือปัญหาพื้นฐาน: คุณจำเป็นต้องคำนวณทั้งทิศทางและขนาดของเวกเตอร์


ขอบคุณสำหรับการช่วยเหลือ. ฉันพยายามใช้เซนต์คิตส์และเนวิสหลังจากที่ฉันคำนวณเวกเตอร์ที่ต่างกันมันก็ใช้งานได้ แต่ดูไม่ดี ฉันพยายามดูว่าฉันคำนวณเวกเตอร์ที่ต่างกัน, ทำให้เป็นมาตรฐาน, แล้วเกลาความเร็ว ตอนนี้มันดูดีขึ้นแล้ว ใช่ฉันคิดว่าฉันต้องการขีปนาวุธกลับบ้านในเกมนี้ในภายหลัง ขอบคุณอีกครั้ง.
Tashu

1
คำตอบนี้ไม่สมเหตุสมผลกับคนอื่นหรือไม่?
BlueRaja - Danny Pflughoeft

@Fxlll: ตกลงฉันคิดว่าฉันเห็นสิ่งที่คุณพยายามจะพูด มีจำนวนมากของปุยไม่เกี่ยวข้องกับคำตอบที่เริ่มต้น / สิ้นสุดของและผมยังสับสนโดยภาษาอังกฤษของคุณ(ซึ่งผมทราบดีว่าอาจจะไม่ได้เป็นความผิดของคุณ) ฉันได้ส่งข้อเสนอแนะการแก้ไขเพื่อล้างคำตอบนี้
BlueRaja - Danny Pflughoeft

@BlueRaja - Danny Pflughoeft ขอบคุณสำหรับความพยายามของคุณ!
FxIII

7

หากเป้าหมายเคลื่อนที่ไปในทิศทางที่มั่นคงด้วยความเร็วคงที่และเส้นทางกระสุนของคุณอยู่ในแนวเส้นตรงที่มีความเร็วคงที่คุณสามารถใช้สมการกำลังสองเพื่อทำนายตำแหน่งที่แน่นอนที่พวกเขาจะตัดและเล็งปืนของหอคอยของคุณ ณ จุดนั้น .

เนื่องจากมีความมั่นใจว่ากระสุนจะกระทบกับเครื่องหมายและคุณสามารถคำนวณเวลาที่แน่นอนจากการยิงไปกระทบไม่ต้องตรวจจับการชนเพียงแค่ยิงปืนรอช่วงเวลาคำนวณลงทะเบียน

นี่คือรหัสเทียมสำหรับสมการกำลังสอง:

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

ขอบคุณสำหรับรหัสหลอกฉันจะตรวจสอบเพื่อดูว่าสมการกำลังสองทำงานกับสถานการณ์นี้อย่างไร ขอบคุณอีกครั้ง.
Tashu

ปัญหาคือว่าผู้ใช้สามารถเคลื่อนไปทางกระสุนและขวาก่อนที่จะตีเขาสามารถหนีจากร่องรอยของกระสุน ในกรณีนี้การแก้ปัญหานี้จะดีพอไหม
มาร์ติน

ไม่ผ่านการรับรองในประโยคแรก นี่ไม่ใช่สำหรับเกมทุกเกม แต่สำหรับเกมที่เป้าหมายเคลื่อนที่ด้วยความเร็วคงที่เท่านั้น ความเร็วคงที่หมายถึงทั้งทิศทางและความเร็ว ตัวอย่างเช่นเกมสไตล์กลาโหมกริดสามารถใช้วิธีการนี้ได้
สตีฟ H

3

คุณต้อง 'ทำนาย' ตำแหน่งของวัตถุตามเวลาที่กระสุนจะถึง คุณสามารถทำได้โดยใช้ความเร็ววัตถุ / ความเร็ว (หวังว่าคงที่;) และมันเป็นเวกเตอร์ทิศทาง

ฉันไม่แน่ใจว่าสูตรที่แน่นอนออกมาจากหัวของฉัน แต่ฉันคิดว่ามันเป็นเช่นนี้:

NewPosition = OldPosition + (ความเร็ว * DirectionVector);

หากคุณมีเส้นทางที่กำหนดไว้คุณจะต้องคำนวณใหม่เมื่อวัตถุเปลี่ยนทิศทาง ใช้ NewPosition นี้ในฐานะที่เป็นเวคเตอร์ของศัตรูของคุณและสัญลักษณ์แสดงหัวข้อย่อยควรจะกระทบกับวัตถุโดยไม่มี 'เอฟเฟกต์ homing' การกลับบ้านเกิดขึ้นเนื่องจากความจริงที่ว่าวัตถุศัตรูเคลื่อนย้ายมาตั้งแต่การคำนวณเวกเตอร์ดั้งเดิมมันสามารถติดตามได้เมื่อวัตถุเคลื่อนที่ในทิศทางเดียวนานพอ

หวังว่าจะช่วย :)


3
หรือคุณสามารถโกงและกดปุ่มอัตโนมัติจากนั้นใช้สไปรต์ที่เคลื่อนที่เป็นคำติชม หรือยิงกระสุนของคุณด้วยความเร็ว 50,000
Jonathan Connell

1

คุณสามารถหลีกเลี่ยงการใช้สแควร์รูทและกำลัง 2

var distX:Float = target.x - x;
var distY:Float = target.y - y;
_velX = distX / timeTravel;
_velY = distY / timeTravel;

// Take out if you want a nice slow down as approaches effect.  
timeTravel -= 1.0; // make sure u have a positive timeTravel.
x += _velX;
y += _velY;

if (distX < 0)
    distX = -distX;

if (distY < 0)
    distY = -distY;

if (_velX < 0)
    _velX = -_velX;

if (_velY < 0)
    _velY = -_velY;

// Should both snap @ the same time.
if (distX < _velX)
x = target.x; // snap & see what happens.

if (distY < _velY)
y = target.y; // snap & see what happens.

// TODO: call your onHitTarget here ...
// Hopefully this shall provide 10x the performance 
// of using Math.sqrt and all the extra multiplications.

มันเขียนจากความทรงจำทั้งหมด โดยวิธีการใช้องค์ประกอบที่ทำงาน - ทดสอบทีละบรรทัดถ้าคุณใหม่ในนี้ Float คือ Number ใน AS3

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.