OK, so you know the position and the velocity of the target, and you know where you are and the speed of your bullets. So where should you aim?
(If you spot mistakes in the following, please correct them, my equation-spinning is a bit rusty.)
Here's the math, skip to the bottom if you only want the code.
The base equation for hitting the target is:
p_shot + v_shot * t = p_target + v_target * t
which gives us the following equation for v_shot:
v_shot = (p_target - p_shot) / t + v_target
let's mark p_target - p_shot with d_p and break it into components:
v_sx = d_px / t + v_tx
v_xy = d_py / t + v_ty
from the speed of the bullet we know that:
|v_s| = sqrt(v_sx**2 + v_sy**2)
and by substituting the shot velocity components with the equations above we get:
|v_s| = sqrt((d_px / t + v_tx)**2 + (d_py / t + v_ty)**2)
which turns into the following after multiplying the terms open:
|v_s| = sqrt((1/t**2)*(d_px**2+d_py**2) + (1/t)*(2*d_px*v_tx + 2*d_py*v_ty) + (v_tx**2 + v_ty**2)
raise both sides to the second power and move all terms on the left side (I'm cutting corners here by assuming the part inside the root is positive). Let's also say that:
a = d_px**2+d_py**2
b = 2*d_px*v_tx + 2*d_py*v_ty
c = v_tx**2 + v_ty**2 - |v_s|**2
Then we get:
a*(1/t**2) + b*(1/t) + c = 0
Now mark t_i = 1/t:
a*t_i**2 + b*t_i + c = 0
Then solve t_i by the quadratic formula, we'll accept only positive t_i, so we discard the other solution (-b - sqrt...):
t_i = (-b + sqrt(b**2 - 4*a*c)) / 2a
From which we get t:
t = 2a / (-b + sqrt(b**2 - 4*a*c))
Okay, t solved. Now we assign t to the target's movement:
p_t + v_t*t = est_p_t
Where est_p_t is the estimated position of the target at the time the shot reaches it. To wrap up, here's roughly the code you need to write:
p_s = self_position
p_t = target_position
v_t = target_velocity
d_px = p_ty - p_sy
d_py = p_ty - p_sy
a = d_px**2 + d_py**2
b = 2*d_px*v_tx + 2*d_py*v_ty
c = v_tx**2 + v_ty**2 - shot_speed**2
t = 2*a / (-b + Math.sqrt(b**2 - 4*a*c))
p_t + v_t*t = est_p_t
aim_gun_at_coords(est_p_t)
fire_when_on_target
If you get a wildly swinging gun, your target position and velocity probably need to be averaged from several observations (e.g. take 20 last scanned positions, split into groups of four, average each group to get 5 positions, then average the velocities between them)
|