Câu trả lời:
Chức năng khay parabol được định nghĩa là:
Fx = Vox*t + Ox;
Fy = -0.5 * g * t * t + Voy*t + Oy;
Các giá trị đã biết:
P: the target point.
O: the origin point.
g: gravity.
t: time needed to impact.
Các giá trị không xác định:
Vo: Initial Velocity
Để tính 'Vo', chúng ta có thể đưa ra các giá trị cho hàm F:
't' = flight time 'duration'
'F' = target point 'P'
(Px-Ox)
Vox = --------
duration
Py + 0.5* g * duration * duration - Oy
Voy = ---------------------------------------
duration
Bây giờ bạn có thể nhận được tất cả các giá trị để đạt được mục tiêu từ gốc cho các giá trị đến t vào phương trình F:
When t = 0 => F == O (Origin)
When t = duration => F == P (Target)
Gần đây tôi đã phải giải quyết một vấn đề tương tự, tôi đã đưa ra hai giải pháp, dựa trên công thức tôi tìm thấy trên trang wikipedia 'Dan the Man' đã được đề cập: Quỹ đạo của một viên đạn
Trong giải pháp này, bạn vô tình cần một trong hai góc phóng cố định hoặc vận tốc x. Vận tốc Y là không cần thiết khi chúng ta phóng đạn theo một góc cụ thể.
Giải pháp 1, góc phóng được cố định, tính vận tốc:
g = 9.81; // gravity
x = 49; // target x
y = 0; // target y
o = 45; // launch angle
v = (sqrt(g) * sqrt(x) * sqrt((tan(o)*tan(o))+1)) / sqrt(2 * tan(o) - (2 * g * y) / x); // velocity
Giải pháp 2, vận tốc là cố định, tính toán góc phóng:
g = 9.81; // gravity
v = 40; // velocity
x = 42; // target x
y = 0; // target y
s = (v * v * v * v) - g * (g * (x * x) + 2 * y * (v * v)); //substitution
o = atan(((v * v) + sqrt(s)) / (g * x)); // launch angle
Trong trường hợp của tôi, giải pháp này hoạt động khá tốt.
Nếu bạn không quan tâm nếu nó đúng về mặt toán học, chỉ cần nó có vẻ đủ chính xác, hãy tính đường thẳng và làm cho đường đạn của bạn đi theo đường đó, nhưng "đẩy nó lên" dọc theo đường bình thường như một hàm của khoảng cách phân khúc dòng, do đó, nó tăng lên khi đến gần giữa phân khúc và rơi xuống khi nó đi ra giữa phân khúc dòng.
Bạn có thể sử dụng sóng hình sin cho việc này, sử dụng phạm vi độ từ -90 đến +90 (trong đó -90 là điểm bên trái trên đoạn thẳng, 90 là điểm phải và bạn lerp ở giữa) và nhân kết quả bởi một hằng số để mở rộng nó lên.
Nếu bạn cần câu trả lời hoàn toàn chính xác về toán học / vật lý, điều này sẽ không có ích. Nếu bạn không, điều này có thể làm việc khá tốt cho bạn!
Đừng quên, lập trình trò chơi là về việc sử dụng ảo ảnh trông chính xác (và rẻ hơn để tính toán), thay vì thực tế.
Nếu bạn chỉ cần một cái gì đó vừa phải và có vận tốc cố định, bạn có thể sử dụng phương pháp rất đơn giản này.
distance = to.x - from.x;
angleToPoint = atan2(to.y - from.y, to.x - from.x);
distanceFactor = 1/1000;
angleCorrection = (PI*0.18) * (distance * distanceFactor);
velocity.X = cos(angleToPoint+angleCorrection) * power;
velocity.Y = sin(angleToPoint+angleCorrection) * power;
Khoảng cách có thể âm nhưng nó vẫn sẽ hoạt động vì góc cũng phụ thuộc vào khoảng cách. Nếu khoảng cách là âm, góc cần thêm cũng là âm.
Bạn sẽ cần chơi xung quanh với distanceFactor để tìm giá trị phù hợp. Nó phụ thuộc vào trọng lực và sức mạnh của đạn. Nó nên được gần 1 chia cho khoảng cách tối đa mà đạn có thể bao phủ.