Con đường tiếp theo với chuyển động giống như tiểu hành tinh. Thời gian hoàn thành con đường


7

Tôi hiện đang tìm hiểu về cách thực hiện việc này, nhưng tốt nhất là đăng vấn đề trước. (đăng trên Vật lý và GameDev, như các bạn biết toán của bạn)

Nó khá khó để giải thích. Vấn đề cụ thể này xoay quanh vấn đề tạo ra một hệ thống dẫn đường cho tàu chạy bằng tên lửa.
Hãy suy nghĩ: 'Tôi muốn con tàu từ trò chơi "Tiểu hành tinh" đi theo một con đường cụ thể và tính toán, toàn bộ chuyến đi sẽ mất bao nhiêu thời gian trước đó "

Một chiếc máy bay có các thuộc tính riêng như gia tốc khối, tuyến tính và góc. Nó chỉ có thể tăng tốc theo hướng chuyển tiếp của nó. Ngoài ra, khá đau trong ... vận tốc di chuyển tối đa của nó bị hạn chế.

Hy vọng rằng hình ảnh sẽ xóa một số điều: nhập mô tả hình ảnh ở đây

Vấn đề nằm ở bước đầu tiên. Chương trình được bắt đầu trong khi tàu đang di chuyển với vận tốc ngẫu nhiên và phải đối mặt với hướng ngẫu nhiên. Để di chuyển hoàn toàn về phía điểm mục tiêu, đầu tiên, tàu phải quay mặt về phía vectơ "U". Nhưng trong khi làm như vậy, nó vẫn di chuyển, vì vậy vectơ "U" sẽ thay đổi. Từ hình ảnh bạn có thể thấy rằng hướng rẽ có thể thay đổi, đừng lo lắng, đó không phải là vấn đề.

Vì vậy, vấn đề. Tôi đã thử chỉ sử dụng toán học vectơ, nhưng không thành công vì biến tôi đang cố gắng tính toán dựa vào các phương trình liên quan đến biến này. Tôi quá ngu ngốc khi chỉ nhận được biến tôi quan tâm ở một mặt của phương trình. Tôi nghĩ rằng giải pháp sẽ liên quan đến một chức năng của khoảng cách từ thủ công đến đối tượng theo thời gian.

[Chỉnh sửa 1]

Cho sự quan tâm của bạn. Đây là phần mà tôi bị mắc kẹt. nhập mô tả hình ảnh ở đây

Từ đầu. Chúng ta có tàu ở vị trí ban đầu "A", di chuyển với vận tốc "V1" và mục tiêu ở vị trí ban đầu "B", với vận tốc "V2" (tốt hơn là chỉ trong trường hợp)

Từ đó chúng ta có thể tính toán vectơ ghi "U", rằng chúng ta cần căn chỉnh bản thân để đi tới mục tiêu với tốc độ "Vmax"

Góc giữa tiêu đề "Cf" và vectơ "U" của thủ công càng lớn, thì thủ công sẽ mất nhiều thời gian hơn. Có nghĩa là, thủ công sẽ bao gồm nhiều khoảng cách hơn trong khi xoay (hình trên cùng). Điều đó có nghĩa là góc sẽ thay đổi trong khi xoay, v.v.

Trên hình thứ hai, trong hộp màu đỏ. ở phía trên, chúng tôi tính toán sản phẩm chấm, ở phía dưới, chúng tôi nhân độ lớn của vectơ. Vì vectơ Cf có độ dài 1 mọi lúc, chúng ta có thể dự phòng nó.

Điều chính tôi đang tìm kiếm là biến "t", hiện tại tôi không có ý tưởng.


@GameAlchemist Tôi quan tâm đến phương pháp của bạn. Muốn dành thời gian để xây dựng? Nếu hiệu suất trong mô phỏng tốt hơn và toán học đủ tối ưu, tôi sẽ không thấy có gì sai khi xấp xỉ một thứ khác :)
Gabriel Rej

Có vẻ như vấn đề toán học thực sự phức tạp. Tôi khuyên bạn nên đăng nó trên Sàn giao dịch Toán học
nikoliazekter

Công cụ trò chơi gì?
Vadim Tatarnikov

@VadimTatarnikov Thống nhất
Gabriel Rej

bán kết đầu tiên: vì B có vận tốc V2 tốn kém, hãy đặt hệ thống vào một tham chiếu làm cho B là một điểm tĩnh. Sau đó xem xét V2 = (0,0,0) và newV1 = V1-V2.
dnk drone.vs.drones

Câu trả lời:


1

Tôi đã làm điều này trước đây. Phương pháp đơn giản nhất là mô phỏng đường đạn, ghi lại các điểm dọc theo quỹ đạo của nó và lưu ý điểm gần nhất với mục tiêu. Sau đó, những gì tôi làm là lấy vị trí của mục tiêu + (vận tốc mục tiêu * thời gian đạt được đến điểm gần nhất *) để có được vị trí của nó vào thời điểm mà viên đạn chạm tới nó. Tất cả những gì bạn cần làm là Math.atan2 tọa độ mới với tọa độ tàu của bạn để có được góc bạn cần để đánh nó (hoặc bạn có thể vẽ một điểm đánh dấu trên HUD tại vị trí mới nếu bạn thích).

Đối với mục đích của tôi, điều này đủ hiệu quả và có thể xử lý nhiều mục tiêu cùng một lúc mà không có bất kỳ cú đánh hiệu suất nào. Nếu bạn muốn nó hiệu quả hơn, chỉ cần nhân tốc độ của vật phóng và đặt ít điểm hơn theo quỹ đạo của nó.

* lưu ý rằng thời gian thực hiện để đạt đến điểm gần nhất là chỉ số của điểm đó trong mảng.

Chỉnh sửa: Theo yêu cầu, bên dưới là mã giả thô cho những gì tôi đã làm, lưu ý rằng cách tôi mô phỏng đạn của tôi có thể sẽ khác với cách bạn phải mô phỏng mã của bạn.

Cũng lưu ý rằng các chức năng dưới đây thuộc về tàu và 'đây' là một tham chiếu đến thể hiện của tàu. Ngoài ra, đây là một số loại java sửa đổi: P

list<Point> targetPoints = new list<Point>();
list<Double> targetRotations = new list<Double>();

//the function you call in your update step:
public void doTargetting(list<Asteroid> targets, int targettingRange) {
    targetPoints.clear(); //reset the list of targets
    targetRotations.clear();

    if(targets.size() == 0)
        return;
    int maxPoints = 50, stepsPerPoint = 3;

    list<Point> mypoints = simulateCurve(maxPoints, stepsPerPoint, myProjectile);
    for(Asteroid a in targets)
    {
        if(distance(a, this) < targettingRange) {
            list<Point> apoints = simulateCurve(maxPoints, stepsPerPoint, a);
            doTargettingFor(a, this, mypoints, apoints);
        }
    }
}

//physics stuff:
public list<Point> simulateCurve(int maxPoints, int stepsPerPoint, GameObject obj) {
    list<Point> points = new list<Point>();
    double velx = obj.velx, vely = obj.vely;
    double accellx = obj.accellx, accelly = obj.accelly;
    double maxSpeed = obj.maxSpeed; //if you want a max speed
    double burnout = obj.burnout; //a point at which the projectile runs out of thruster juice
    double loss = 1 - obj.friction; //velocity loss in each step, because space dust or something?
    double x = 0, y = 0;

    points.add({x, y});

    int spl = 0; //counter for steps per line
    for(int i=0; i<maxPoints*stepsPerPoint; i++) {
        if(burnout != 0 && i < burnout) {
            velx += accellx; 
            vely += accelly;
        }

        velx *= loss;
        vely *= loss;

        double mag = Math.hypot(velx, vely);
        if(maxSpeed != 0 && mag > maxSpeed) {
            double mul = maxSpeed/mag;
            velx *= mul;
            vely *= mul;
        }

        x += velx;
        y += vely;

        spl++;
        if(spl > stepsPerLine) {
            spl = 0;
            points.add({x, y});
        }
    }

    return points;
}

//targetting stuff:
public void doTargettingFor(GameObject a, Ship me, list<Point> mypoints, list<Point> apoints) {
    int closestIndex = 0;
    double closest = MAX_VALUE; //a really really big number
    for(int i=0; i<points.size(); i++) {
        double distance = Math.hypot((apoints[i].x+a.x) - (mypoints[i].x+me.x), (apoints[i].y+a.y) - (mypoints[i].y+me.y));
        if(distance < closest) {
            closest = distance;
            closestIndex = i;
        }
    }

    if(closest < a.radius) //note that this handy little statement checks if you're on target and will hit ;). I used this to change the colour of the marker on the HUD to help you 'lock on' as it were.
    {
    }

    //this bit looks complicated but it really isn't. I'm taking the simulated points of the asteroid and adding it to the asteroid's current coordinates, then doing the same for the projectile
    targetPoints.add({apoints[closestIndex].x + a.x, apoints[closestIndex].y + a.y});
    targetRotations.add(Math.atan2((apoints[closestIndex].y + a.y) - (mypoints[closestIndex].y + me.y), (apoints[closestIndex].x + a.x) - (mypoints[closestIndex].x + me.x)));

}

Bạn có muốn đăng một đoạn mã của bạn ở đây hoặc một cái gì đó làm cho nó rõ ràng chính xác như thế nào bạn đã làm nó?
Majte

1
Chà, trong trường hợp của tôi, tôi đã viết vật lý đằng sau tất cả các đối tượng trò chơi, vì vậy thật dễ dàng để tôi mô phỏng chúng. Tôi đoán tôi có thể tóm tắt nó là mã giả. Hãy cho tôi khoảng nửa giờ để viết nó và kiểm tra lại.
Merivo

Ok, tôi đã kiểm tra nó ngay bây giờ và nó có vẻ theo thứ tự.
Merivo

Làm tốt. Tôi thích cách tiếp cận này và tôi có một triển khai tương tự, vì vậy tôi không muốn đăng nó ở đây vì nó sẽ làm lại những gì bạn đã đăng. Cảm ơn!
Majte
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.